CountDownLatch:
/**
* CountDownLatch:每次执行countDown方法,count减1,直到count为0,
* 所有在CountDownLatch上await的线程都将结束await继续运行
*
* 一个或多个线程到达await等待,直到count为0,这些线程就可以继续运行
*
* await:等待count==0
* countDown:count-1
*/
public class CountDownLatchDemo {
private static class Task implements Runnable {
CountDownLatch startSignal;
CountDownLatch doneSignal;
Task(CountDownLatch startSignal, CountDownLatch doneSignal) {
this.startSignal = startSignal;
this.doneSignal = doneSignal;
}
@Override
public void run() {
try {
startSignal.await();
System.out.println(Thread.currentThread().getName() + " started...");
doneSignal.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) throws Exception {
CountDownLatch startSignal = new CountDownLatch(1); // 需要countDown一次
CountDownLatch doneSignal = new CountDownLatch(5); // 需要countDown五次
for (int i = 0; i < 5; i++) {
new Thread(new Task(startSignal, doneSignal)).start();
}
System.out.println(Thread.currentThread().getName() + " prepared...");
startSignal.countDown();
doneSignal.await();
System.out.println("All thread done...");
}
}
CyclicBarrier:
/**
* CyclicBarrier:当在CyclicBarrier上await的线程到达parties数量时,
* 所有线程都结束await,继续向下执行,若传入了barrierAction,则await
* 线程到达了parties数量时,先执行barrierAction,然后所有线程结束await
* 继续执行
*
* CyclicBarrier能重复执行,也就是说再次执行await的线程数量到达
* parties时,能够继续触发
*
* await:等待其他线程await,直到执行await线程达到一定数量,结束await
*/
public class CyclicBarrierDemo {
public static void main(String[] args) {
CyclicBarrier cyclicBarrier = new CyclicBarrier(5, () -> System.out.println("ok"));
for (int i = 0; i < 5; i++) { // 开启5个线程调用await方法
new Thread(() -> {
for (int j = 0; j < 3; j++) { // 每个线程循环3次
System.out.println(Thread.currentThread().getName() + " begin...");
try {
cyclicBarrier.await(); // 直到5个线程都到达这里,全部结束await,继续执行
} catch (BrokenBarrierException e) {
System.err.println(e.getMessage());
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " end...");
}
}).start();
}
}
}
Semaphore:
/**
* Semaphore:类似于具有数量限制的共享锁,每次acquire减少permits数量,
* 每次release返还permits,只有permits大于0,才能acquire成功,继续执行
* 能够实现限制同时访问资源的线程数量
*
* acquire:申请,成功则继续执行,失败则等待其他线程释放
* release:释放
*/
public class SemaphoreDemo {
public static void main(String[] args) {
Semaphore semaphore = new Semaphore(3);
for (int i = 0; i < 9; i++) {
new Thread(() -> {
try {
semaphore.acquire();
System.out.println(Thread.currentThread().getName() + " get permit...");
TimeUnit.SECONDS.sleep(1);
semaphore.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
}
}
}
Exchanger:
/**
* Exchanger:当两个线程均到达exchange方法后,两者交换对象
*/
public class ExchangerDemo {
private static class Item {
private String name;
Item(String name) {
this.name = name;
}
@Override
public String toString() {
return "Item{" +
"name='" + name + '\'' +
'}';
}
}
public static void main(String[] args) {
Exchanger<Item> exchanger = new Exchanger<>();
new Thread(() -> {
try {
Item x = new Item("xxx");
TimeUnit.SECONDS.sleep(1);
System.out.println(Thread.currentThread().getName() + " has prepared: " + x);
Item y = exchanger.exchange(x);
System.out.println(Thread.currentThread().getName() + " get: " + y);
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
new Thread(() -> {
try {
Item y = new Item("yyy");
TimeUnit.SECONDS.sleep(1);
System.out.println(Thread.currentThread().getName() + " has prepared: " + y);
Item x = exchanger.exchange(y);
System.out.println(Thread.currentThread().getName() + " get: " + x);
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
}
}