JDK-In-Action-CountDownLatch-CyclicBarrier-Semaphore
并发工具
闭锁 CountDownLatch
栅栏 CyclicBarrier
信号量 Semaphore
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个许可