Latch有“门锁”的意思,当门没有打开时,N个人不能进入屋内的,也就是N个线程是不能继续向下运行的,支持这样的特性可以控制线程执行任务的时机,使线程以“组团”的方式一起执行任务。
实现等待与继续运行的效果分别需要使用await()和countDown()方法来进行。调用await()方法时判断计数是否为0,如果不为0则呈现等待状态。其他线程可以调用countDown()方法将计数减1,当计数减到为0时,呈等待的线程继续运行。而方法getCount()就是获得当前的计数个数。
初步使用
public class MyService {
private CountDownLatch down = new CountDownLatch(1);
public void testMethod() {
try {
System.out.println("A");
down.await();
System.out.println("B");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void downMethod() {
System.out.println("X");
down.countDown();
}
}
public class MyThread extends Thread {
private MyService myService;
public MyThread(MyService myService) {
super();
this.myService = myService;
}
@Override
public void run() {
myService.testMethod();
}
}
public class Run {
public static void main(String[] args) throws InterruptedException {
MyService service = new MyService();
MyThread t = new MyThread(service);
t.start();
Thread.sleep(2000);
service.downMethod();
}
}
运行效果:
A
X
B
代码new CountDownLatch(1)的作用是创建1个计数的CountDownLatch类的对象,当线程执行down.await()代码时呈等待状态,程序不向下继续运行。程序执行down.countDown()代码时计数由1变为0,以前呈等待状态的线程继续向下运行。
各就各位准备比赛
本实验想要实现的是裁判员要等待所有运动员各就各位全部准备完毕,再开始比赛的效果。
public class MyThread extends Thread {
private CountDownLatch comingTag; //裁判等待所有运动员到来
private CountDownLatch waitTag; //等待裁判说准备开始
private CountDownLatch waitRunTag; //等待起跑
private CountDownLatch beginTag; //起跑
private CountDownLatch endTag; //所有运动员到达终点
public MyThread(CountDownLatch comingTag, CountDownLatch waitTag, CountDownLatch waitRunTag, CountDownLatch beginTag, CountDownLatch endTag) {
super();
this.comingTag = comingTag;
this.waitTag = waitTag;
this.waitRunTag = waitRunTag;
this.beginTag = beginTag;
this.endTag = endTag;
}
@Override
public void run() {
try {
System.out.println("运动员使用不同交通工具不同速度到达起跑点,正向这头走!" + Thread.currentThread().getName());
Thread.sleep((int) (Math.random() * 10000));
System.out.println(Thread.currentThread().getName() + "到起跑点了!");
comingTag.countDown();
System.out.println("等待裁判说准备!");
waitTag.await();
System.out.println("各就各位!准备起跑姿势!");
Thread.sleep((int) (Math.random() * 10000));
waitRunTag.countDown();
beginTag.await();
System.out.println(Thread.currentThread().getName() + " 运动员起跑 并且跑赛过程用时不确定");
Thread.sleep((int) (Math.random() * 10000));
endTag.countDown();
System.out.println(Thread.currentThread().getName() + " 运动员到达终点");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class Run {
public static void main(String[] args) {
try {
CountDownLatch comingTag = new CountDownLatch(10);
CountDownLatch waitTag = new CountDownLatch(1);
CountDownLatch waitRunTag = new CountDownLatch(10);
CountDownLatch beginTag = new CountDownLatch(1);
CountDownLatch endTag = new CountDownLatch(10);
MyThread[] threadArray = new MyThread[10];
for (int i = 0; i < threadArray.length; i++) {
threadArray[i] = new MyThread(comingTag, waitTag, waitRunTag, beginTag, endTag);
threadArray[i].start();
}
System.out.println("裁判员在等待选手的到来!");
comingTag.await();
System.out.println("裁判看到所有运动员来了,各就各位前“巡视”用时5秒");
Thread.sleep(5000);
waitTag.countDown();
System.out.println("各就各位!");
waitRunTag.await();
Thread.sleep(2000);
System.out.println("发令抢响起!");
beginTag.countDown();
endTag.await();
System.out.println("所有运动员到达,统计比赛名次!");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
运行效果:
运动员使用不同交通工具不同速度到达起跑点,正向这头走!Thread-1
运动员使用不同交通工具不同速度到达起跑点,正向这头走!Thread-5
运动员使用不同交通工具不同速度到达起跑点,正向这头走!Thread-3
裁判员在等待选手的到来!
运动员使用不同交通工具不同速度到达起跑点,正向这头走!Thread-4
运动员使用不同交通工具不同速度到达起跑点,正向这头走!Thread-2
运动员使用不同交通工具不同速度到达起跑点,正向这头走!Thread-0
运动员使用不同交通工具不同速度到达起跑点,正向这头走!Thread-7
运动员使用不同交通工具不同速度到达起跑点,正向这头走!Thread-6
运动员使用不同交通工具不同速度到达起跑点,正向这头走!Thread-8
运动员使用不同交通工具不同速度到达起跑点,正向这头走!Thread-9
Thread-9到起跑点了!
等待裁判说准备!
Thread-1到起跑点了!
等待裁判说准备!
Thread-2到起跑点了!
等待裁判说准备!
Thread-3到起跑点了!
等待裁判说准备!
Thread-0到起跑点了!
等待裁判说准备!
Thread-5到起跑点了!
等待裁判说准备!
Thread-6到起跑点了!
等待裁判说准备!
Thread-7到起跑点了!
等待裁判说准备!
Thread-8到起跑点了!
等待裁判说准备!
Thread-4到起跑点了!
等待裁判说准备!
裁判看到所有运动员来了,各就各位前“巡视”用时5秒
各就各位!
各就各位!准备起跑姿势!
各就各位!准备起跑姿势!
各就各位!准备起跑姿势!
各就各位!准备起跑姿势!
各就各位!准备起跑姿势!
各就各位!准备起跑姿势!
各就各位!准备起跑姿势!
各就各位!准备起跑姿势!
各就各位!准备起跑姿势!
各就各位!准备起跑姿势!
发令抢响起!
Thread-1 运动员起跑 并且跑赛过程用时不确定
Thread-7 运动员起跑 并且跑赛过程用时不确定
Thread-2 运动员起跑 并且跑赛过程用时不确定
Thread-0 运动员起跑 并且跑赛过程用时不确定
Thread-3 运动员起跑 并且跑赛过程用时不确定
Thread-9 运动员起跑 并且跑赛过程用时不确定
Thread-4 运动员起跑 并且跑赛过程用时不确定
Thread-5 运动员起跑 并且跑赛过程用时不确定
Thread-6 运动员起跑 并且跑赛过程用时不确定
Thread-8 运动员起跑 并且跑赛过程用时不确定
Thread-1 运动员到达终点
Thread-8 运动员到达终点
Thread-9 运动员到达终点
Thread-4 运动员到达终点
Thread-6 运动员到达终点
Thread-7 运动员到达终点
Thread-5 运动员到达终点
Thread-3 运动员到达终点
Thread-0 运动员到达终点
Thread-2 运动员到达终点
所有运动员到达,统计比赛名次!