一、参考blog
https://www.cnblogs.com/dolphin0520/p/3920397.html
二、CountDownLatch
个人把它类比于一个持有计数的闸门,每到达这个闸门一个线程,计数减1,当计数为0时再执行闸门后续的动作。同时闸门失效了(只能用一次)。
public static void main(String[] args) { Executor fix = Executors.newFixedThreadPool(5); CountDownLatch latch = new CountDownLatch(2); Runnable runner = () -> { System.out.println("[" + Thread.currentThread().getName() + "]" + " started"); System.out.println("[" + Thread.currentThread().getName() + "]" + " finished"); latch.countDown(); }; fix.execute(runner); fix.execute(runner); try { System.out.println("[" + Thread.currentThread().getName() + "]" + " waiting on latch..."); latch.await(); System.out.println("[" + Thread.currentThread().getName() + "]" + " ok, i can do my work"); } catch (InterruptedException e) { e.printStackTrace(); } }
三、CyclicBarrier
用法差不多,特点:可以重复使用。
public static void main(String[] args) { Executor fix = Executors.newFixedThreadPool(5); CyclicBarrier barrier = new CyclicBarrier(2); Runnable runner = () -> { try { Thread.sleep(new Random().nextInt(10000)); System.out.println("[" + Thread.currentThread().getName() + "]" + " wait on barri " + new Date()); barrier.await(); System.out.println("[" + Thread.currentThread().getName() + "]" + " condition ok, do my work " + System.currentTimeMillis()); } catch (InterruptedException e) { e.printStackTrace(); } catch (BrokenBarrierException e) { e.printStackTrace(); } }; fix.execute(runner); fix.execute(runner); }
四、Semaphore
向量,有点像锁。
import java.util.Date; import java.util.Random; import java.util.concurrent.*; public class Test { // public static void main(String[] args) { Executor fix = Executors.newFixedThreadPool(5); Semaphore semaphore = new Semaphore(2); Runnable runner = () -> { try { semaphore.acquire(); System.out.println("[" + Thread.currentThread().getName() + "]" + " get a semaphore " + new Date()); Thread.sleep(2000); System.out.println("[" + Thread.currentThread().getName() + "]" + " release a semaphore " + new Date()); semaphore.release(); } catch (InterruptedException e) { e.printStackTrace(); } }; for (int i = 0; i < 5; i++) { fix.execute(runner); } }