4、JUC--CountDownLatch闭锁
CountDownLatch
Java 5.0 在 java.util.concurrent 包中提供了多种并发容器类来改进同步容器的性能。
CountDownLatch 一个同步辅助类,在完成一组正在其他线程中执行的操作
之前,它允许一个或多个线程一直等待。
闭锁可以延迟线程的进度直到其到达终止状态,闭锁可以用来确保某些活
动直到其他活动都完成才继续执行:
确保某个计算在其需要的所有资源都被初始化之后才继续执行;
确保某个服务在其依赖的所有其他服务都已经启动之后才启动;
等待直到某个操作所有参与者都准备就绪再继续执行
闭锁:
在完成某些运算时,只有其他所有线程的运算全部完成,当前运算才继续执行
案例:测试线程执行的时间
public class TestCountDownLatch { public static void main(String[] args) { final CountDownLatch latch = new CountDownLatch(5); LatchDemo ld = new LatchDemo(latch); //计算执行时间 long start = System.currentTimeMillis(); for(int i=0;i<10;i++){ new Thread(ld).start(); } long end = System.currentTimeMillis(); System.out.println("线程执行的时间为:" + (start -end)); } } class LatchDemo implements Runnable{ private CountDownLatch countDownLatch; public LatchDemo(CountDownLatch latch){ this.countDownLatch = latch; } @Override public void run() { for(int i= 0;i<5000;i++){ if(i%2==0){ System.out.println(i); } } } }
此时无法得到10个子线程的执行时间
因为在子线程执行完成之前main函数的线程已经执行完毕
此时我们需要设置main函数线程在10个子线程执行完毕之后再执行
进行修改设置:
public class TestCountDownLatch { public static void main(String[] args) { final CountDownLatch latch = new CountDownLatch(10); LatchDemo ld = new LatchDemo(latch); //计算执行时间 long start = System.currentTimeMillis(); for(int i=0;i<10;i++){ new Thread(ld).start(); } try { latch.await(); } catch (InterruptedException e) { e.printStackTrace(); } long end = System.currentTimeMillis(); System.out.println("线程执行的时间为:" + (start -end)); } } class LatchDemo implements Runnable{ private CountDownLatch countDownLatch; public LatchDemo(CountDownLatch latch){ this.countDownLatch = latch; } @Override public void run() { synchronized(this){ try { for(int i= 0;i<5000;i++){ if(i%2==0){ System.out.println(i); } } } finally { //递减1 countDownLatch.countDown(); } } } }
main函数中有10个线程
所以需要设置10个闭锁
每个线程执行之后都需要将其的值进行减一
所以在线程中:
synchronized:此时可能出现同部数据的设置
使用CountDownLatch的countDown()方法将其值进行递减1
同时需要使用await()放法进行等待所有线程执行完成之后再执行之后的代码
所以会在最后进行打印10个线程消耗的时间: