Java并发编程学习笔记8

88 阅读2分钟

阻塞方法与中断方法

Thread提供了interrupt方法用于中断一个线程以及用于查询线程是否被中断。每个线程都有一个布尔属性来表示它的中断状态;中断一个线程会设置此状态。

中断是一种协作机制。一个线程不能强迫另一个线程停止它正在做的事情并做其他事情;当线程 A 中断线程 B 时,A 只是请求 B 在到达一个方便的停止点时停止它正在做的事情——如果它愿意的话。

当您的代码调用一个抛出 InterruptedException 异常的方法时,您的方法也是一个阻塞方法,并且必须有一个响应中断的计划。对于库代码,基本上有两种选择:

传播 InterruptedException

如果您可以摆脱它,这通常是最明智的策略——只需将 InterruptedException 传播给您的调用者。这可能涉及不捕获 InterruptedException,或者捕获它并在执行一些简短的特定于活动的清理后再次抛出它

恢复中断

有时您不能抛出 InterruptedException,例如当您的代码是 Runnable 的一部分时。在这些情况下,您必须捕获 InterruptedException 并通过在当前线程上调用中断来恢复中断状态,以便调用堆栈上层的代码可以看到发出了中断。

闭锁

闭锁是一种同步工具类,可以延迟线程的进度直到其达到终止状态。

CountDownLatch

CountDownLatch 是一种灵活的闭锁实现,可用于任何这些情况;它允许一个或多个线程等待一组事件的发生。闩锁状态由一个初始化为正数的计数器组成,表示要等待的事件数。 countDown 方法递减计数器,表示事件已发生,await 方法等待计数器归零,这在所有事件都已发生时发生。如果计数器在进入时不为零,则 await 会阻塞,直到计数器达到零、等待线程被中断或等待超时。

FutureTask

由 FutureTask 表示的计算是用 Callable 实现的,Callable 是 Runnable 的结果承载等价物,并且可以处在三种状态:等待运行、正在运行或已完成。完成包括计算可以完成的所有方式,包括正常完成、取消和异常。一旦 FutureTask 进入完成状态,它将永远保持在该状态。

Semaphores(信号量)

计数信号量用于控制可以同时访问特定资源或执行给定操作的活动数量。计数信号量可用于实现资源池或对集合施加限制。

Barriers

屏障类似latches,因为它们会阻塞一组线程,直到发生某些事件。关键区别在于,对于Barriers,所有线程必须同时聚集在屏障点才能继续。latches用于等待事件;Barriers用于等待其他线程。