多线程-闭锁
闭锁
闭锁是一种同步工具类,可以延迟线程的进度知道其到达终止状态。
闭锁的作用相当于一扇门:在闭锁到达结束状态前,这扇门一直是关闭的,并且没有任何线程可以通过,当到达结束状态时,这扇门会打开并允许所有的线程通过。
当闭锁到达结束状态后,将不会再改变状态,因此这扇门将永远保持打开状态。
闭锁可以用来确保某些活动直到其他活动都完成后才继续执行。例如
确保某个计算在其需要的所有资源都初始化之后才继续执行。
确保某个服务在其依赖的所有其他服务都已经启动之后才气动。
等待直到某个操作的所有参与者都就绪再继续执行。
CountDownLatch类
CountDownLatch类是一种灵活的闭锁实现,可以在上述各种情况中使用,他可以使一个或多个线程等待一组事件发生。
CountDownLatch类包括一个计数器,该计数器初始化为一个正数,表示需要等待的事件数量。countDown方法递减计数器,表示有一个时间已经发生了,而await方法会暂停线程一直到计数器到达0。计数器到达0,表示所有需要等待的事件都已经发生,此时会打开线程大门,放出所有被阻塞的线程。
public class CountDownLatchDemo {
public static void main(String[] args) throws InterruptedException {
//阻塞main线程的“大门”,需要有另外10个线程都准备好,才会解开
CountDownLatch mainGate = new CountDownLatch(10);
//阻塞其他线程的“大门”,需要main线程打开
CountDownLatch otherGate = new CountDownLatch(1);
//创建10个线程
for (int i = 0; i < 10; i++) {
new Thread(() -> {
try {
//该线程准备好后,将mainGate的值减1,当10个线程都准备好后,mainGate自然被置为0
mainGate.countDown();
//使用otherGate阻塞当前线程,知道otherGate的值被置为0
otherGate.await();
long startTime = System.currentTimeMillis();
int num = 0;
for (int j = 0; j < 100000; j++) {
num += j;
}
long endTime = System.currentTimeMillis();
System.out.println(Thread.currentThread() + ":使用了" + (endTime - startTime) + "毫秒");
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
}
//main线程在此阻塞,直到10个线程都准备好
mainGate.await();
//打开其他线程的大门
otherGate.countDown();
}
}