java - FutureTask 实现重新读取状态以防止泄漏中断
问题描述
FutureTask
以下是Java中一些方法的实现:
run
方法:
public void run() {
if (state != NEW ||
!UNSAFE.compareAndSwapObject(this, runnerOffset,
null, Thread.currentThread()))
return;
try {
Callable<V> c = callable;
if (c != null && state == NEW) {
V result;
boolean ran;
try {
result = c.call();
ran = true;
} catch (Throwable ex) {
result = null;
ran = false;
setException(ex);
}
if (ran)
set(result);
}
} finally {
// runner must be non-null until state is settled to
// prevent concurrent calls to run()
runner = null;
// state must be re-read after nulling runner to prevent
// leaked interrupts
int s = state;
if (s >= INTERRUPTING)
handlePossibleCancellationInterrupt(s);
}
}
cancel
方法:
public boolean cancel(boolean mayInterruptIfRunning) {
if (!(state == NEW &&
UNSAFE.compareAndSwapInt(this, stateOffset, NEW,
mayInterruptIfRunning ? INTERRUPTING : CANCELLED)))
return false;
try { // in case call to interrupt throws exception
if (mayInterruptIfRunning) {
try {
Thread t = runner;
if (t != null)
t.interrupt();
} finally { // final state
UNSAFE.putOrderedInt(this, stateOffset, INTERRUPTED);
}
}
} finally {
finishCompletion();
}
return true;
}
handlePossibleCancellationInterrupt
方法:
private void handlePossibleCancellationInterrupt(int s) {
// It is possible for our interrupter to stall before getting a
// chance to interrupt us. Let's spin-wait patiently.
if (s == INTERRUPTING)
while (state == INTERRUPTING)
Thread.yield(); // wait out pending interrupt
// assert state == INTERRUPTED;
// We want to clear any interrupt we may have received from
// cancel(true). However, it is permissible to use interrupts
// as an independent mechanism for a task to communicate with
// its caller, and there is no way to clear only the
// cancellation interrupt.
//
// Thread.interrupted();
}
我知道这些方法是以这种方式实现的,以防止 run 方法在cancel
方法完成中断线程之前完成,并且状态已更改为interrupting
,interrupted
但我无法理解两件事:
为什么运行方法中有这些代码行:
int s = state;
if (s >= INTERRUPTING)
handlePossibleCancellationInterrupt(s);
无法更改为此:
if (state == INTERRUPTING)
handlePossibleCancellationInterrupt(state);
所以我无法理解两件事:
- 这个声明的作用是什么
int s = state
- 为什么
state >= INTERRUPTING
语句不能改成这个state == INTERRUPTING
解决方案
1.效果int s = state
state
作为一个volatile
变量,必须是将其分配给 的主要原因s
。这样,我们可以避免if
语句中额外的昂贵的易失性读取访问。
2.state >= INTERRUPTING
可能最初有讨论重置interrupted
线程的状态handlePossibleCancellationInterrupt()
。
下面的块评论在handlePossibleCancellationInterrupt()
// We want to clear any interrupt we may have received from // cancel(true). However, it is permissible to use interrupts // as an independent mechanism for a task to communicate with // its caller, and there is no way to clear only the // cancellation interrupt. // // Thread.interrupted();
清除中断应该已经发生,即使状态是INTERRUPTED
.
推荐阅读
- reactjs - 出现未经授权的错误:需要完全身份验证才能访问此资源
- c# - Xamarin Forms ListView,当TranslateTo动画被其他项目隐藏时
- python - 使用 jenkins shell 调用 python 问题 sshpass 命令未找到
- arrays - 在 Dart 中合并子列表
- python-3.x - 如何找到熊猫列中连续零的最大计数?
- vba - 如果我用不同的名称保存演示文稿,功能区菜单宏会失败
- kdb - KDB+:如何检索符合特定逻辑的给定行之前和之后的行?
- bash - 如何减去和除以bash脚本中的值,我也想以百分比的形式知道
- react-native - React Native - React Navigation Bottom Tab 包含 WebView 时的缓慢转换(滞后)
- excel - 将公式分配给与特定单元格相关的名称(名称管理器)