换句话说,我想知道在中断线程中检测到中断时,在中断之前更改变量是否始终可见。 E.g。
private int sharedVariable;
public static void interruptTest() {
Thread someThread = new Thread(() -> {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// Is it here guaranteed that changes before interrupt are always visible here?
System.out.println(sharedVariable);
}
});
someThread.start();
Thread.sleep(1000);
sharedVariable = 10;
someThread.interrupt();
}
我试图在Java language specification中找到答案
Summary page of the java.util.concurrent package中提及Java tutorial,但未提及interrupt
。
我知道volatile
和其他同步原语但我需要它们吗?
答案 0 :(得分:4)
是的,从线程T1中断线程T2会在T1和T2之间创建发生之前的关系,如JLS 17.4.4中所述。同步订单:
如果线程T1中断线程T2,则T1中断 与任何其他线程(包括T2)的任何点同步 确定T2已被中断(通过具有 抛出InterruptedException或通过调用Thread.interrupted或 Thread.isInterrupted)。
现在这只暗示T1 同步 - 检测到中断T2,而你问及发生在之前。幸运的是,前者暗示后者来自 17.4.5。发生在订单之前:
可以通过先发生关系来排序两个动作。如果一个 行动发生在另一个之前,然后第一个是可见的和 在第二天之前订购。
如果我们有两个动作x和y,我们写hb(x,y)来表示x 在y之前发生。
- ...
- 如果动作x与后续动作y同步,那么我们也有hb(x,y)。
因此,即使没有sharedVariable
,您也可以安全地访问volatile
知道它(至少)有T1写入的值。