java.util.concurrent(J.U.C)大大提升了并发性能,AQS 被认为是 J.U.C 的核心。java
用来控制一个线程等待多个线程。bash
维护了一个计数器 cnt,每次调用 countDown() 方法会让计数器的值减 1,减到 0 的时候,那些由于调用 await() 方法而在等待的线程就会被唤醒。并发
public class CountdownLatchExample {
public static void main(String[] args) throws InterruptedException {
final int totalThread = 10;
CountDownLatch countDownLatch = new CountDownLatch(totalThread);
ExecutorService executorService = Executors.newCachedThreadPool();
for (int i = 0; i < totalThread; i++) {
executorService.execute(() -> {
System.out.print("run..");
countDownLatch.countDown();
});
}
countDownLatch.await();
System.out.println("end");
executorService.shutdown();
}
}
run..run..run..run..run..run..run..run..run..run..end复制代码
用来控制多个线程互相等待,只有当多个线程都到达时,这些线程才会继续执行。函数
和 CountdownLatch 类似,都是经过维护计数器来实现的。线程执行 await() 方法以后计数器会减 1,并进行等待,直到计数器为 0,全部调用 await() 方法而在等待的线程才能继续执行。性能
CyclicBarrier 和 CountdownLatch 的一个区别是,CyclicBarrier 的计数器经过调用 reset() 方法能够循环使用,因此它才叫作循环屏障。ui
CyclicBarrier 有两个构造函数,其中 parties 指示计数器的初始值,barrierAction 在全部线程都到达屏障的时候会执行一次。this
public CyclicBarrier(int parties, Runnable barrierAction) {
if (parties <= 0) throw new IllegalArgumentException();
this.parties = parties;
this.count = parties;
this.barrierCommand = barrierAction;
}
public CyclicBarrier(int parties) {
this(parties, null);
}复制代码
public class CyclicBarrierExample {
public static void main(String[] args) {
final int totalThread = 10;
CyclicBarrier cyclicBarrier = new CyclicBarrier(totalThread);
ExecutorService executorService = Executors.newCachedThreadPool();
for (int i = 0; i < totalThread; i++) {
executorService.execute(() -> {
System.out.print("before..");
try {
cyclicBarrier.await();
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
}
System.out.print("after..");
});
}
executorService.shutdown();
}
}
before..before..before..before..before..before..before..before..before..before..after..after..after..after..after..after..after..after..after..after..复制代码
Semaphore 相似于操做系统中的信号量,能够控制对互斥资源的访问线程数。spa
如下代码模拟了对某个服务的并发请求,每次只能有 3 个客户端同时访问,请求总数为 10。操作系统
public class SemaphoreExample {
public static void main(String[] args) {
final int clientCount = 3;
final int totalRequestCount = 10;
Semaphore semaphore = new Semaphore(clientCount);
ExecutorService executorService = Executors.newCachedThreadPool();
for (int i = 0; i < totalRequestCount; i++) {
executorService.execute(()->{
try {
semaphore.acquire();
System.out.print(semaphore.availablePermits() + " ");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
semaphore.release();
}
});
}
executorService.shutdown();
}
}
复制代码
2 1 2 2 2 2 2 1 2 2复制代码