Java中的同步工具类

178 阅读2分钟

CountDownLatch

Java中的CountDownLatch是一种闭锁机制,用于同步线程操作。其初始化时需要一个非负计数器,表示需要等待线程的数量。coundDown方法递减该计数器,await等待计数器变为0,如果该计数器为0,那么await会一直等待或中断或等待超时

FutureTask

FutureTask也是一种闭锁机制,表示一种可生成结果的运算,其计算结果通过Callable实现,表示一种可得到结果的Runnable。FutureTask包含三种状态:等待运行,运行中,运行完成。其中完成状态又分为正常结束,由于取消而技术以及因为异常而结束。通过get方法可以获得执行结果,如果未处于完成状态,则get方法会阻塞直到完成状态。此外,get方法会产生ExecutionException异常和InterruptedException异常。

ExecutionException异常分为以下三种情况:

  1. Callable抛出的受检异常
  2. RuntimeException
  3. 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是一种两方栅栏,各方在栅栏位置交换数据