CountDownLatch两种用法
1.当前线程等待其他线程执行完毕后在执行。
2.模拟高并发场景。
在多线程编程里,CountDownLatch是一个很好的计数器工具。
常用的两个方法:
1、计数器减一
public void countDown() {
sync.releaseShared(1);
}
2、线程等待,在计算器未到达0之前会一直等待
public void await() throws InterruptedException {
sync.acquireSharedInterruptibly(1);
}
好,下面来演示两个demo.
1、等待所有子线程执行完成后再执行主线程的情况
2、模拟高并发的情况
package com.figo.study.test; import java.util.concurrent.CountDownLatch;
public class TestSomething { public static void main(String[] args) { //testWaitThread(); testConcurrent(); } /** * 1、模拟所有子线程都执行完成后再执行主线程 * countdownLatch计数,模拟子线程执行完成之后再执行主线程 * 这个也可以用future来实现 * */ public static void testWaitThread() { final CountDownLatch latch = new CountDownLatch(2); new Thread(){ public void run() { try { System.out.println("子线程"+Thread.currentThread().getName()+"正在执行"); Thread.sleep(3000); System.out.println("子线程"+Thread.currentThread().getName()+"执行完毕"); latch.countDown(); } catch (InterruptedException e) { e.printStackTrace(); } }; }.start(); new Thread(){ public void run() { try { System.out.println("子线程"+Thread.currentThread().getName()+"正在执行"); Thread.sleep(3000); System.out.println("子线程"+Thread.currentThread().getName()+"执行完毕");
latch.countDown(); } catch (InterruptedException e) { e.printStackTrace(); } }; }.start();
try { System.out.println("等待2个子线程执行完毕..."); latch.await(); System.out.println("2个子线程已经执行完毕"); System.out.println("继续执行主线程"); } catch (InterruptedException e) { e.printStackTrace(); } } /** * 线程数量 */ public static final int THREAD_NUM = 100; /** * 开始时间 */ private static long startTime = 0L; /** * 2、模拟高并发 */ public static void testConcurrent() { try { startTime = System.currentTimeMillis();
System.out.println("CountDownLatch started at: " + startTime); // 初始化计数器为1 CountDownLatch countDownLatch = new CountDownLatch(1);
for (int i = 0; i < THREAD_NUM; i ++) { new Thread(new Run(countDownLatch)).start(); } // 启动多个线程 countDownLatch.countDown(); } catch (Exception e) { System.out.println("Exception: " + e); } } /** * 线程类 */ private static class Run implements Runnable { private final CountDownLatch startLatch;
public Run(CountDownLatch startLatch) { this.startLatch = startLatch; }
@Override public void run() { try { // 线程等待 startLatch.await(); // 模拟耗时操作 Thread.sleep(3000); long endTime = System.currentTimeMillis(); System.out.println(Thread.currentThread().getName() + " ended at: " + endTime + ", cost: " + (endTime - startTime) + " ms."); } catch (Exception e) { e.printStackTrace(); } } } }