CountDownLatch的使用方式和场景
一.描述
CountDownLatch是一个用来线程同步的工具,CountDownLatch会初始化一个计时器,通过countdown()方法进行计数递减,
并在在计数器归零之前,执行到await()的线程就会进入等待,等计数器归零,等待线程就会继续执行.
二.应用场景
1.在N个线程执行完毕再开始执行某一线程
public static void main(String[] args) { CountDownLatch countDownLatch = new CountDownLatch(2); new Thread(() -> { System.out.println("执行线程" + Thread.currentThread().getName()); countDownLatch.countDown(); }, "线程A").start(); new Thread(() -> { System.out.println("执行线程" + Thread.currentThread().getName()); try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); } countDownLatch.countDown(); }, "线程B").start(); System.out.println(Thread.currentThread().getName() + "等待 A, B 线程"); try { countDownLatch.await(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "线程执行结束"); }
执行效果:
执行线程线程A
main等待 A, B 线程
执行线程线程B
main线程执行结束
2.让N个线程在某个条件并行执行
public static void main(String[] args) { CountDownLatch countDownLatch = new CountDownLatch(1); //AtomicInteger计数,确认两个线程都准备好后开始并行执行 AtomicInteger atomicInteger = new AtomicInteger(); new Thread(() -> { System.out.println(Thread.currentThread().getName() + "线程准备完成"); atomicInteger.incrementAndGet(); try { countDownLatch.await(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("执行线程" + Thread.currentThread().getName()); }, "线程A").start(); new Thread(() -> { //本线程延迟两秒 try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "线程准备完成"); atomicInteger.incrementAndGet(); try { countDownLatch.await(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("执行线程" + Thread.currentThread().getName()); }, "线程B").start(); while(atomicInteger.get() < 2) { try { Thread.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } } countDownLatch.countDown(); System.out.println("A, B线程开始并行执行"); }
执行效果:
线程A线程准备完成
线程B线程准备完成
A, B线程开始并行执行
执行线程线程A
执行线程线程B