1.countDownLatch(闭锁)
countDownLatch基于AQS的成员变量state实现的计数器,每次执行countDown()方法时,计数器减1,执行await()方法会阻塞线程直到计数器为0。我的理解 就类似一个大门一样,当计数器为0 大门才会打开,所有的线程才能通过大门,继续执行。一般用在多任务执行,最后汇总(即最终的操作依赖于所有子任务执行完成的结果),所有子任务完成之后,才能进行最终操作,代码示例如下
public static void main(String[] args) throws InterruptedException { CountDownLatch countDownLatch = new CountDownLatch(2); ExecutorService executorService = Executors.newFixedThreadPool(2); executorService.submit(()->{ try { Thread.sleep(10); System.out.println("child threadOne over"); } catch (InterruptedException e) { e.printStackTrace(); }finally { countDownLatch.countDown(); } }); executorService.submit(()-> { try { Thread.sleep(10); System.out.println("child threadTwo over"); } catch (InterruptedException e) { e.printStackTrace(); }finally { countDownLatch.countDown();//原子操作,同时只能有一个线程操作计数器 } }); Thread.sleep(1000); System.out.println("wait all child thread over"); try { countDownLatch.await(2, TimeUnit.SECONDS);//调用await()会一直阻塞,直到countDown计数器为0 (大门一直关闭,直到计数器为0打开),并发继续执行 System.out.println("all child thread over"); //调用await(2, TimeUnit.SECONDS) ,超过这个时间,(大门打开)线程不阻塞,并发继续执行 } catch (InterruptedException e) { e.printStackTrace(); } executorService.shutdown(); }
2.Cyclicbarrier(回环屏障)
类似于闭锁(也通过计数器实现),每个线程执行完任务之后,执行await()方法,计数器减1,阻塞自己,直到所有线程都执行await()方法,即到达栅栏的位置,栅栏打开,然后可以执行一个所有子线程全部到达屏障后的任务。栅栏之后会被重置,以便于下次使用。(而闭锁是一次性的)。代码示例如下;
/** * 假设一个任务分三步,每一步让两个线程并发执行,下一步执行的条件是上一步必须执行完。 */public class CyclicBarrierDemo2 { private static CyclicBarrier cyclicBarrier = new CyclicBarrier(2); public static void main(String[] args) { ExecutorService executorService = Executors.newFixedThreadPool(2); executorService.execute(() -> { try { System.out.println(Thread.currentThread() + "step1"); cyclicBarrier.await(); System.out.println(Thread.currentThread() + "step2"); cyclicBarrier.await(); System.out.println(Thread.currentThread() + "step3"); }catch (Exception e) { } }); executorService.execute(() -> { try { System.out.println(Thread.currentThread() + "step1"); cyclicBarrier.await(); System.out.println(Thread.currentThread() + "step2"

