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

Tom*_*mas 8 java concurrency multithreading

换句话说,我想知道在中断线程中检测到中断时,在中断之前更改变量是否始终可见.例如

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();
}
Run Code Online (Sandbox Code Playgroud)

我试图找到答案在Java语言规范java.util.concurrent包的摘要页中提到的Java教程,但interrupt并没有提及.

我知道volatile和其他同步原语但我需要它们吗?

Bee*_*ope 7

是的,如JLS 17.4.4 中所述,从线程 T1 中断线程 T2在 T1 和 T2 之间创建发生在之前的关系同步顺序

如果线程 T1 中断线程 T2,则 T1 的中断与任何其他线程(包括 T2)确定 T2 已被中断(通过抛出 InterruptedException 或通过调用 Thread.interrupted 或 Thread.isInterrupted)的任何点同步。

现在这仅意味着 T1中断 T2 的检测同步,而您询问了之前发生的情况。幸运的是,前者从17.4.5 开始暗示了后者发生在订单之前

两个动作可以通过happens-before 关系排序。如果一个动作发生在另一个之前,那么第一个动作对第二个动作可见并在第二个动作之前排序。

如果我们有两个动作 x 和 y,我们写 hb(x, y) 来表示 x 发生在 y 之前。

  • ...
  • 如果一个动作 x 与随后的动作 y 同步,那么我们也有 hb(x, y)。

因此sharedVariable,即使没有volatile.