第八章 Java 中的并发工具类
8.1 CountDownLatch 等待多线程完成
CountDownLatch 允许一个或多个线程等待其他线程完成操作。
CountDownLatch 在构造时接收 int 参数作为计数器,当线程执行到 countDown 是,计数器数值 N - 1 。可以是 1 个线程执行 N 个步骤,也可以是多个线程共同执行 N 个步骤。
await 方法会使线程进入等待状态,如果线程执行过久,可以使用 await(long time,TimeUnit unit),等待特定时间。
8.2 CyclicBarrier 同步屏障
CyclicBarrier 意思为可循环使用的屏障,当一组达到一个屏障时被阻塞,知道最后一个线程到达屏障时,屏障才会打开,所有被屏障拦截的线程才会继续运行。
CountDownLatch 的计数器只能使用一次
8.2.1 CyclicBarrier
CyclicBarrier(int parties) 构造函数的参数表示需要屏障拦截的线程数量,线程调用 await 方法通知 CyclicBarrier 已到达屏障,然后线程被阻塞。
- 如果 parties 参数为 3,但是只有两个线程执行 await 方法,那么这两个线程会一直阻塞
- 构造函数:CyclicBarrier(int parties,Runnable barrierAction) ,会在线程到达屏障时,优先执行 barrierAction,方便处理更复杂的业务场景。
- getNumberWaiting :获取 CyclicBarrier 阻塞的线程数量
- isBroken() :用来了解阻塞的线程是否被中断
- reset() :重置 CyclicBarrier 的计数器
8.3 Semaphore 控制并发线程数
Semaphore(信号量)用来控制同时访问特定资源的线程数量,通过协调各个线程,以保证合理使用公共资源。
1. 应用场景
Semaphore 可以用于流量控制,特别是公共资源有限的应用场景,如数据库连接等。比如几十条线程并发读取数据,但是数据库只支持10个连接数,此时就需要使用 Semaphore 做流量控制,否则会报错,无法获取数据库连接。
Semaphore 的常用方法:
- acquire() :获取一个许可证
- release() :释放一个许可证
- tryAcquire:尝试获取许可证
- int availablePermits():返回此信号量中当前可用的许可证数
- int getQueueLength():返回正在等待获取许可证的线程数
- boolean hasQueuedThreads():是否有线程正在等待获取许可证
- void reducePermits(int reduction):减少reduction 个许可证(protected方法)
- Collection getQueuedThreads():返回所有等待获取许可证的线程集合(protected方法)
8.4 Exchanger 线程间交换数据
Exchange(交换者)是一个用于线程间协作的工具类。
Exchanger 用于进行线程间的数据交换。它提供一个同步点,在这个同步点,两个线程可以交换彼此的数据。
当第一个线程先执行 exchange() 方法,它会一直等待第二个线程也执行 exchange 方法,当两个线程都到达同步点后,会将彼此线程生产出来的数据传递给对方。
应用场景:
- Exchanger 可以用于遗传算法
- 如AB进行交配,当交换数据后使用交叉规则得出两个交配结果
- Exchanger 可以用于校对工作
- 如A、B线程同时执行,结果是否相同
如果有一个线程一直未执行 exchange() ,则会一直等待。可以使用 exchange(V x,long timeout,TimeUnit unit) 设置最大等待时间。