ReetrantLock:可重入锁,lock()几次就需要unlock()几次

Condition:实现await()和signal()来和锁实现等待通知机制

Semaphore: 信号量,指定数量的线程可以访问资源,控制并发访问量,防止计算机资源耗尽。可以通过多次调用release()来增加初始许可,

ReentrantReadWriteLock: 读写锁,读-读能并发,读-写和写-写会相互阻塞

CountDownLatch: 倒计时器,每当一个线程完成任务,会数字减一,调用await()的线程会等待计时器清0后,再继续进行下去。

public class CountDownLatchTest implements Runnable {
static final Lock lock = new ReentrantLock();
static final CountDownLatch end = new CountDownLatch(10);
static final CountDownLatchTest demo = new CountDownLatchTest();
@Override
public void run() {
try {
Thread.sleep(new Random().nextInt(10)*100);
lock.lock();
System.out.println("check complete "+end.getCount());
lock.unlock();
end.countDown();
}catch (InterruptedException ex){}
}
public static void main(String...args) throws InterruptedException {
ExecutorService exec = Executors.newFixedThreadPool(10);
for (int i = 0;i < 10;i++){
exec.submit(demo);
}
end.await();
System.out.println("Fire!!!");
exec.shutdown();
}
}
CyclicBarrier: 循环栅栏,必须等待到足够数量的线程,才能执行任务。带重置功能的CountDownLatch, 能重复使用。
它要做的事情是,让一组线程到达一个屏障(也可以叫同步点)时被阻塞,直到最后一个线程到达屏障时,屏障才会开门,所有被屏障拦截的线程才会继续干活。CyclicBarrier默认的构造方法是CyclicBarrier(int parties),其参数表示屏障拦截的线程数量,每个线程调用await方法告诉CyclicBarrier我已经到达了屏障,然后当前线程被阻塞。
CyclicBarrier还提供一个更高级的构造函数CyclicBarrier(int parties, Runnable barrierAction),用于在要求数量线程全都到达屏障时,优先执行barrierAction,方便处理更复杂的业务场景。
CyclicBarrier和CountDownLatch的区别
CountDownLatch的计数器只能使用一次。而CyclicBarrier的计数器可以使用reset() 方法重置。所以CyclicBarrier能处理更为复杂的业务场景,比如如果计算发生错误,可以重置计数器,并让线程们重新执行一次。
CyclicBarrier还提供其他有用的方法,比如getNumberWaiting方法可以获得CyclicBarrier阻塞的线程数量。isBroken方法用来知道阻塞的线程是否被中断。比如以下代码执行完之后会返回true。

public class CyclicBarrierTest {
public static class Soldier implements Runnable{
private String soldier;
private final CyclicBarrier barrier;
public Soldier(String soldier, CyclicBarrier barrier) {
this.soldier = soldier;
this.barrier = barrier;
}
@Override
public void run() {
try {
barrier.await();
doWork();
barrier.await();
}catch (InterruptedException ex){
ex.printStackTrace();
}catch (BrokenBarrierException e){
e.printStackTrace();
}
}
void doWork(){
try {
Thread.sleep(Math.abs(new Random().nextInt()%10000));
}catch (InterruptedException e){
e.printStackTrace();
}
System.out.println(soldier+" has finished the job");
}
public static class BarrierRun implements Runnable{
boolean flag;
int N;
public BarrierRun(boolean flag, int n) {
this.flag = flag;
N = n;
}
@Override
public void run() {
if (flag){
System.out.println("Soldiers of numbers "+N+" has finished jobs");
}else {
System.out.println("Soldiers of numbers "+N+" has collected");
flag = true;
}
}
}
public static void main(String...args){
final int N = 10;
Thread[] allSoldiers = new Thread[N];
boolean flag = false;
CyclicBarrier cyclicBarrier = new CyclicBarrier(N,new BarrierRun(flag,N));
System.out.println("集合队伍");
for (int i = 0;i < 10;i++){
System.out.println("Solider "+i+" say hi");
allSoldiers[i] = new Thread(new Soldier("Soldier "+i,cyclicBarrier));
allSoldiers[i].start();
}
}
}
}
Phaser: 增强版的CyclicBarrier。
arriveAndAwaitAdvance(): 等待足够数量的线程,在前进到下一个阶段(的wait?)。
arriveAndDeregister(): 到达并退出Phaser,Phaser的parties也会永久减一。
getPhase(): 获取这是第几个arrive…()的线程。
register(): 动态增加一个parties
getRegisteredParties(): 获得注册的parties数量。
bulkRegister(num): 增加num数量的parties
arrive(): 会使getArrivedParties()返回的值加一,但不会阻塞等待
awaitAdvance(int phase): 如果phase==getPhase(),则堵塞等待,否则继续运行。
forceTermination(): 使得Phaser对象的屏障功能失效,使得等待中的线程继续完成任务。

Exchanger: 在两个线程之间传递任意类型的数据,exchange是阻塞进行的。使用超时版本会抛出异常。

LockSupport: 线程堵塞工具,可以在任意位置让线程堵塞。park()和unpark()是对suspend()和resume()的改进,但不会出现死锁等现象,也不用获取锁。如果在park()状态时,调用线程的interrupt(),会从WAITING状态返回。
