CountDownLatch
Java中的CountDownLatch是一种闭锁机制,用于同步线程操作。其初始化时需要一个非负计数器,表示需要等待线程的数量。coundDown方法递减该计数器,await等待计数器变为0,如果该计数器为0,那么await会一直等待或中断或等待超时
FutureTask
FutureTask也是一种闭锁机制,表示一种可生成结果的运算,其计算结果通过Callable实现,表示一种可得到结果的Runnable。FutureTask包含三种状态:等待运行,运行中,运行完成。其中完成状态又分为正常结束,由于取消而技术以及因为异常而结束。通过get方法可以获得执行结果,如果未处于完成状态,则get方法会阻塞直到完成状态。此外,get方法会产生ExecutionException异常和InterruptedException异常。
ExecutionException异常分为以下三种情况:
- Callable抛出的受检异常
- RuntimeException
- Error
信号量
计数信号量Semaphore用于控制同时访问某个资源的数量或同时执行某个操作的数量,初始化数量可以由构造函数指定,在随后的操作中,首先获取数量,在执行完指定操作之后释放数量
栅栏
Barrier区别于闭锁。闭锁用于等待事件的发生,栅栏用于等待其他线程,并且栅栏可以重用而闭锁不能。此外CyclicBarrier的构造函数接受一个Runnable,在最后一个线程到达时可以调用Runnable方法
示例:
public static void main(String[] args) {
int needWaitThreadNum = 2;
CyclicBarrier cyclicBarrier = new CyclicBarrier(needWaitThreadNum, () -> System.out.println(Thread.currentThread().getName() + "Done"));
System.out.println("Starting new Thread");
for (int i = 0; i < needWaitThreadNum; i++) {
new Thread(() -> {
System.out.println(Thread.currentThread().getName() + "is Running");
try {
System.out.println(Thread.currentThread().getName() + "ready to sleep");
Thread.sleep(2000);
System.out.println(Thread.currentThread().getName() + "wake up");
cyclicBarrier.await();
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
}
}).start();
}
System.out.println("End");
}
Output:
Starting new Thread
End
Thread-0is Running
Thread-1is Running
Thread-1ready to sleep
Thread-0ready to sleep
Thread-1wake up
Thread-0wake up
Thread-0Done
Exchanger
Exchanger是一种两方栅栏,各方在栅栏位置交换数据