简介
Latch即为门闩的意思,它所表达的意思是:当门没有打开时,所有的人都无法进入,即所有的线程也无所谓继续向下运行,这样可以控制线程执行任务的时机,使线程可以以组团的方式一起执行任务,CountDownLatch类所提供的功能是判断count计数不为0时,当前线程是wait状态,即都处于阻塞等待。同时CountDownLatch类也是一个具有同步功能的辅助类,使用效果是 给定一个计数,当时用这个CountDownLatch类的线程判断计数不为0时,则呈wait状态,如果为0时则继续运行。实现等待和继续运行的效果分别需要使用await()和countDown()方法来进行。调用await()方法时判断计数是否为0,如果不为0则呈等待状态。其他线程可以调用countDown()方法将计数减1,当计数减到0时,呈等待状态的线程继续运行。而方法getCount()就是获得当前的计数个数,需要注意的是,计数值无法被重置,计数是减法操作
API使用
1.1、await()以及countDwon()方法的使用
案例
public class MyService {
//创建1个计数的实例
private CountDownLatch downLatch = new CountDownLatch(1);
public void testMethod() {
try {
System.out.println("A");
//执行await方法时,程序被阻塞
downLatch.await();
System.out.println("B");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void downMethod() {
System.out.println("X");
//当计数为0时,程序继续运行
downLatch.countDown();
}
}
public class MyThread extends Thread {
private MyService service;
public MyThread(MyService service) {
super();
this.service = service;
}
@Override
public void run() {
service.testMethod();
}
}
public class Run {
public static void main(String[] args) throws InterruptedException {
MyService service = new MyService();
MyThread thread = new MyThread(service);
thread.start();
Thread.sleep(2000);
service.downMethod();
}
}
运行结果如下:
1.2、await(long timeout, TimeUnit unit)的使用
此方法的作用是使线程在指定的最大时间单位内进入WAITING状态,如果超过这个时间则自动唤醒,程序继续向下运行。
案例如下:
public class MyService {
//创建1个计数的实例
private CountDownLatch downLatch = new CountDownLatch(1);
public void testMethod() {
try {
System.out.println(Thread.currentThread().getName()+"准备"+System.currentTimeMillis());
//执行await方法时,程序被阻塞3秒
downLatch.await(3,TimeUnit.SECONDS);
System.out.println(Thread.currentThread().getName()+"结束"+System.currentTimeMillis());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class MyThread extends Thread {
private MyService service;
public MyThread(MyService service) {
super();
this.service = service;
}
@Override
public void run() {
service.testMethod();
}
}
public class Run {
public static void main(String[] args) throws InterruptedException {
MyService service = new MyService();
MyThread[] threadArray = new MyThread[3];
for (int i = 0; i < threadArray.length; i++) {
threadArray[i] = new MyThread(service);
}
for (int i = 0; i < threadArray.length; i++) {
threadArray[i].start();
}
}
}
运行结果如下:
1.3、getCount()的使用
getCount()获取当前计数的值
案例如下:
public class Run {
public static void main(String[] args) throws InterruptedException {
CountDownLatch count = new CountDownLatch(3);
System.out.println("main getCount1="+count.getCount());
count.countDown();
System.out.println("main getCount2="+count.getCount());
count.countDown();
System.out.println("main getCount3="+count.getCount());
count.countDown();
System.out.println("main getCount4="+count.getCount());
count.countDown();
System.out.println("main getCount5="+count.getCount());
count.countDown();
System.out.println("main getCount6="+count.getCount());
}
}
结果如下: