JDK-In-Action-CountDownLatch-CyclicBarrier-Semaphore

并发工具

闭锁 CountDownLatch

1

栅栏 CyclicBarrier

2

信号量 Semaphore

3

API Example

并发有序执行三个任务

假设有3个任务,A,B,C,要求C执行时A,B已完成.A,B执行顺序无要求

 int n = 2;
 CountDownLatch latch = new CountDownLatch(n);
 ExecutorService service = Executors.newCachedThreadPool();
 int[] r = new int[3];
 service.submit(() -> {
     try {
         latch.await();
     } catch (InterruptedException e) {
         throw new RuntimeException(e);
     }
     r[2] = r[0] + r[1];
     Logger.log("C任务完成:" + r[2]);
 });
 service.submit(() -> {
     r[0] = (int) Math.ceil(Math.random() * 100);
     Logger.log("A任务完成:" + r[0]);
     latch.countDown();
 });
 service.submit(() -> {
     r[1] = (int) Math.ceil(Math.random() * 100);
     Logger.log("B任务完成:" + r[1]);
     latch.countDown();
 });

 service.shutdown();
 service.awaitTermination(30, TimeUnit.SECONDS);
11:14:51.935 Thread[pool-1-thread-2,5,main] A任务完成:51
11:14:51.934 Thread[pool-1-thread-3,5,main] B任务完成:41
11:14:51.962 Thread[pool-1-thread-1,5,main] C任务完成:92

并发执行2个任务的三个有序步骤

假设有2个任务A,B,每个任务都分三个步骤1,2,3,要求全部任务都完成同一个步骤才可以继续下一个步骤

 int n = 2;
 CyclicBarrier cyclicBarrier = new CyclicBarrier(n);
 ExecutorService service = Executors.newCachedThreadPool();
 int[] r = new int[2];
 service.submit(() -> {
     try {
         r[0] = (int) Math.ceil(Math.random() * 100);
         Logger.log("A任务完成1:" + r[0]);
         cyclicBarrier.await();
         r[0] += (int) Math.ceil(Math.random() * 100);
         Logger.log("A任务完成2:" + r[0]);
         cyclicBarrier.await();
         r[0] += (int) Math.ceil(Math.random() * 100);
         Logger.log("A任务完成3:" + r[0]);

     } catch (InterruptedException | BrokenBarrierException e) {
         throw new RuntimeException(e);
     }
 });
 service.submit(() -> {
     try {
         r[1] = (int) Math.ceil(Math.random() * 100);
         Logger.log("B任务完成1:" + r[1]);
         cyclicBarrier.await();
         r[1] += (int) Math.ceil(Math.random() * 100);
         Logger.log("B任务完成2:" + r[1]);
         cyclicBarrier.await();
         r[1] += (int) Math.ceil(Math.random() * 100);
         Logger.log("B任务完成3:" + r[1]);
     } catch (InterruptedException | BrokenBarrierException e) {
         throw new RuntimeException(e);
     }
 });

 service.shutdown();
 service.awaitTermination(30, TimeUnit.SECONDS);
11:15:05.961 Thread[pool-1-thread-1,5,main] A任务完成1:82
11:15:05.961 Thread[pool-1-thread-2,5,main] B任务完成1:46
11:15:05.989 Thread[pool-1-thread-2,5,main] B任务完成2:95
11:15:05.989 Thread[pool-1-thread-1,5,main] A任务完成2:121
11:15:05.989 Thread[pool-1-thread-1,5,main] A任务完成3:192
11:15:05.989 Thread[pool-1-thread-2,5,main] B任务完成3:110

信号量的许可授予同步

 int n = 5;
 Semaphore semaphore = new Semaphore(n);
 Logger.log("创建" + n + "个许可");
 ExecutorService service = Executors.newCachedThreadPool();

 service.submit(() -> {
     try {
         Logger.log("A需要1个许可");
         semaphore.acquire(1);
         Logger.log("A得到1个许可");
         sleep(10);
         Logger.log("A完成任务,并释放1个许可");
         semaphore.release(1);
     } catch (InterruptedException e) {
         throw new RuntimeException(e);
     }
 });
 service.submit(() -> {
     try {
         Logger.log("B需要3个许可");
         semaphore.acquire(3);
         Logger.log("B得到3个许可");
         sleep(20);
         Logger.log("B完成任务第一步,释放2个许可");
         semaphore.release(2);
         sleep(10);
         Logger.log("B完成任务第二步,释放1个许可");
         semaphore.release(1);
     } catch (InterruptedException e) {
         throw new RuntimeException(e);
     }
 });

 service.submit(() -> {
     try {
         Logger.log("C需要4个许可");
         semaphore.acquire(4);
         Logger.log("C得到4个许可");
         sleep(30);
         Logger.log("C完成任务,释放4个许可");
         semaphore.release(4);
     } catch (InterruptedException e) {
         throw new RuntimeException(e);
     }
 });

 service.shutdown();
 service.awaitTermination(30, TimeUnit.SECONDS);
11:15:09.689 Thread[main,5,main] 创建5个许可
11:15:09.725 Thread[pool-1-thread-1,5,main] A需要1个许可
11:15:09.725 Thread[pool-1-thread-2,5,main] B需要3个许可
11:15:09.725 Thread[pool-1-thread-2,5,main] B得到3个许可
11:15:09.725 Thread[pool-1-thread-1,5,main] A得到1个许可
11:15:09.726 Thread[pool-1-thread-3,5,main] C需要4个许可
11:15:09.736 Thread[pool-1-thread-1,5,main] A完成任务,并释放1个许可
11:15:09.746 Thread[pool-1-thread-2,5,main] B完成任务第一步,释放2个许可
11:15:09.747 Thread[pool-1-thread-3,5,main] C得到4个许可
11:15:09.757 Thread[pool-1-thread-2,5,main] B完成任务第二步,释放1个许可
11:15:09.822 Thread[pool-1-thread-3,5,main] C完成任务,释放4个许可

引用

posted @ 2020-05-13 22:43  onion94  阅读(122)  评论(0编辑  收藏  举报