在与中断线程的关系之前,是否在线程上调用interrupt()

时间:2017-07-23 19:30:09

标签: java multithreading concurrency

换句话说,我想知道在中断线程中检测到中断时,在中断之前更改变量是否始终可见。 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和其他同步原语但我需要它们吗?

1 个答案:

答案 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写入的值。