CountDownLatch详解
概念
-
CountDownLatch是⼀个同步⼯具类,它允许⼀个或多个线程⼀直等待,直到其他线程执⾏完后再执⾏。例如,应⽤程序的主线程希望在负责启动框架服务的线程已经启动所有框架服务之后执⾏。
CountDownLatch的⽤法
-
CountDownLatch典型⽤法1:某⼀线程在开始运⾏前等待n个线程执⾏完毕。将CountDownLatch的计数器初始化为n new CountDownLatch(n) ,每当⼀个任务线程执⾏完毕,就将计数器减1 countdownlatch.countDown(),当计数器的值变为0时,在CountDownLatch上 await() 的线程就会被唤醒。⼀个典型应⽤场景就是启动⼀个服务时,主线程需要等待多个组件加载完毕,之后再继续执⾏。
-
CountDownLatch典型⽤法2:实现多个线程开始执⾏任务的最⼤并性。注意是并⾏性,不是并发,强调的是多个线程在某⼀时刻同时开始执⾏。类似于赛跑,将多个线程放到起点,等待发令枪响,然后同时开跑。做法是初始化⼀个共享的CountDownLatch(1),将其计数器初始化为1,多个线程在开始执⾏任务前⾸先 coundownlatch.await(),当主线程调⽤countDown() 时,计数器变为0,多个线程同时被唤醒
CountDownLatch原理
-
CountDownLatch是通过⼀个计数器来实现的,计数器的初始化值为线程的数量。每当⼀个线程完成了⾃⼰的任务后,计数器的值就相应得减1。当计数器到达0时,表⽰所有的线程都已完成任务,然后在闭锁上等待的线程就可以恢复执⾏任务。
-
CountDownLatch使⽤例⼦
-
public static void main(String[] args) throws InterruptedException { CountDownLatch latch = new CountDownLatch(10); for (int i=0; i<9; i++) { new Thread(new Runnable() { @Override public void run() { System.out.println(Thread.currentThread().getName() + " 运⾏"); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } finally { latch.countDown(); } } }).start(); } System.out.println("等待⼦线程运⾏结束"); latch.await(10, TimeUnit.SECONDS); System.out.println("⼦线程运⾏结束"); }
-
⼦线程等待主线程处理完毕开始处理,⼦线程处理完毕后,主线程输出
-
class MyRunnable implements Runnable { private CountDownLatch countDownLatch; private CountDownLatch await; public MyRunnable(CountDownLatch countDownLatch, CountDownLatch await) { this.countDownLatch = countDownLatch; this.await = await; } @Override public void run() { try { countDownLatch.await(); System.out.println("⼦线程" +Thread.currentThread().getName()+ "处理⾃⼰事情"); Thread.sleep(1000); await.countDown(); } catch (InterruptedException e) { e.printStackTrace(); } } }