1.简介
CountDownLatch是一个同步工具类,它允许一个或多个线程一直等待,直到其他线程的操作执行完后再执行。
2.常用API
Method | Description |
---|---|
void await() | Causes the current thread to wait until the latch has counted down to zero, unless the thread is interrupted. |
boolean await(long timeout, TimeUnit unit) | Causes the current thread to wait until the latch has counted down to zero, unless the thread is interrupted, or the specified waiting time elapses. |
void countDown() | Decrements the count of the latch, releasing all waiting threads if the count reaches zero. |
long getCount() | Returns the current count. |
3.常用API使用
-
主线程在等threadA执行完毕
public class TempDemo { public static void main(String[] args) throws Exception { CountDownLatch countDownLatch = new CountDownLatch(1); Thread threadA = new Thread(()->{ for (int index = 0; index < Integer.MAX_VALUE / 10; index ++) { String ss = new String(); Math.random(); } System.out.println(Thread.currentThread().getName() + " 执行完毕, countDown:" + countDownLatch.getCount()); countDownLatch.countDown(); }); threadA.start(); countDownLatch.await(); System.out.println(Thread.currentThread().getName() + " 执行完毕, countDown:" + countDownLatch.getCount()); } }
-
使用await超时(在没有countdown之前,主线程就执行完毕了)
public class TempDemo { public static void main(String[] args) throws Exception { CountDownLatch countDownLatch = new CountDownLatch(1); Thread threadA = new Thread(()->{ for (int index = 0; index < Integer.MAX_VALUE / 10; index ++) { String ss = new String(); Math.random(); } System.out.println(Thread.currentThread().getName() + " 执行完毕, countDown:" + countDownLatch.getCount()); countDownLatch.countDown(); }); threadA.start(); countDownLatch.await(1, TimeUnit.SECONDS); System.out.println(Thread.currentThread().getName() + " 执行完毕, countDown:" + countDownLatch.getCount()); } }
-
线程中断
public class TempDemo { public static void main(String[] args) throws Exception { final CountDownLatch countDownLatch = new CountDownLatch(1); Thread threadA = new Thread(()->{ try { countDownLatch.await(); System.out.println(Thread.currentThread().getName() + " 执行完毕, countDown:" + countDownLatch.getCount()); } catch (InterruptedException e) { e.printStackTrace(); } }); threadA.start(); Thread.sleep(500); threadA.interrupt(); } }
4.常见使用场景
-
最大并行性(10个线程并行)
public class TempDemo { public static void main(String[] args) throws Exception { final CountDownLatch threadLatch = new CountDownLatch(10); final CountDownLatch mainLatch = new CountDownLatch(1); for(int index = 0; index < 10; index ++) { new Thread(()->{ try { threadLatch.countDown(); System.out.println(Thread.currentThread().getName() + " 准备好.."); mainLatch.await(); System.out.println(Thread.currentThread().getName() + " 开始执行.."); } catch (InterruptedException e) { e.printStackTrace(); } }).start(); } threadLatch.await(); System.out.println(Thread.currentThread().getName() + " 让他们并发执行吧"); mainLatch.countDown(); } }
-
死锁检测(test方法会出现死锁,当10个线程并发调用test方法的时候,出现死锁)
public class TempDemo { private static ReentrantLock lockA = new ReentrantLock(); private static ReentrantLock lockB = new ReentrantLock(); public static void lockMethod01() { lockA.lock(); lockB.lock(); lockB.unlock(); lockA.unlock(); } public static void lockMethod02() { lockB.lock(); lockA.lock(); lockA.unlock(); lockB.unlock(); } public static void test() { Thread threadA = new Thread(() -> { lockMethod01(); }); Thread threadB = new Thread(() -> { lockMethod02(); }); threadA.start(); threadB.start(); } public static void main(String[] args) throws Exception { final CountDownLatch threadLatch = new CountDownLatch(10); final CountDownLatch mainLatch = new CountDownLatch(1); for(int index = 0; index < 10; index ++) { new Thread(()->{ try { threadLatch.countDown(); System.out.println(Thread.currentThread().getName() + " 准备好.."); mainLatch.await(); System.out.println(Thread.currentThread().getName() + " 开始执行.."); test(); } catch (InterruptedException e) { e.printStackTrace(); } }).start(); } threadLatch.await(); System.out.println(Thread.currentThread().getName() + " 让他们并发执行吧"); mainLatch.countDown(); } }
-
开始执行前,等待N个线程执行完毕(主线程等待10个线程执行完毕)
public class TempDemo { public static void main(String[] args) throws Exception { final CountDownLatch threadLatch = new CountDownLatch(10); for(int index = 0; index < 10; index ++) { new Thread(()->{ System.out.println(Thread.currentThread().getName() + " 执行完毕"); threadLatch.countDown(); }).start(); } threadLatch.await(); System.out.println(Thread.currentThread().getName() + " 执行完毕"); } }