[英]FutureTask Implementation re-read state to prevent leaked intterupts
Here is the implementation of some methods of FutureTask
in Java:下面是Java中
FutureTask
的一些方法的实现:
run
method: 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
Method: 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
method: 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();
}
I know these methods are implemented this way to prevent the run method to finish before interrupting the thread in cancel
method finished and the state has changed from interrupting
to interrupted
but I can't understand two things:我知道这些方法是以这种方式实现的,以防止 run 方法在
cancel
方法完成中断线程之前完成,并且 state 已从interrupting
变为interrupted
,但我无法理解两件事:
Why these lines of code in run method:为什么运行方法中有这些代码行:
int s = state;
if (s >= INTERRUPTING)
handlePossibleCancellationInterrupt(s);
could not be changed to this one:无法更改为此:
if (state == INTERRUPTING)
handlePossibleCancellationInterrupt(state);
So I can't understand two things:所以我无法理解两件事:
int s = state
int s = state
state >= INTERRUPTING
statement can not be changed to this one state == INTERRUPTING
state >= INTERRUPTING
语句不能改成这一条state == INTERRUPTING
int s = state
int s = state
state
being a volatile
variable, must be the predominant reason for assigning it to s
. state
是一个volatile
变量,必须是将其分配给s
主要原因。 This way, we can avoid an additional costlier volatile read access within the if
statement.这样,我们可以避免在
if
语句中进行额外的成本更高的易失性读取访问。
The links here and here discusses about volatile read performance. 此处和此处的链接讨论了易失性读取性能。
state >= INTERRUPTING
state >= INTERRUPTING
May be initially there were discussions to reset the interrupted
status of the thread in handlePossibleCancellationInterrupt()
.最初可能有讨论在
handlePossibleCancellationInterrupt()
中重置线程的interrupted
状态。
Below block commented in 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();
Clearing the interrupt should have happen, even in case the state is INTERRUPTED
.即使 state 是
INTERRUPTED
,也应该清除中断。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.