0

运行主程序

public class ThreadTest {
volatile int p = 0, q = 0;
  public void test() throws InterruptedException {
        Thread writeThread = new Thread(){
            public void run(){
                while (!isInterrupted()) {
                    p++;
                    q++;
                }
            }
        };
        Thread readThread = new Thread(){
            public void run(){
                while (!isInterrupted()) {
                    //p should not be less than q
                    if(p<q){
                        System.out.println("happen before violation p = " + p + ";q = " + q);
                    }
                }
            }
        };
        writeThread.start();
        readThread.start();
        Thread.currentThread().sleep(2);
        writeThread.interrupt();
        readThread.interrupt();
  }

  public static void main(String[] args) throws InterruptedException {
    new ThreadTest().test();
  }
}

输出

在违规之前发生 p = 736;q = 827
在违规之前发生 p = 4635;q = 4657
在违规之前发生 p = 6421;q = 6440
在违规之前发生 p = 8719;q = 8803

4

1 回答 1

0

您应该在q之后阅读p以确保它们的值处于“不小于”顺序:

int q_value = q; // Read 'q' once
int p_value = p; // Read 'p' AFTER q
if(p_value < q_value) // ... happens-before violation

在这种情况下,仅q需要volatile修饰符,并且可以在不违反约束的情况下对p省略它。

在您的原始代码中,没有什么可以阻止编译器读取p BEFORE q。所以 readThread 可以从 writeThread的第 736 次迭代中看到p值,但从第 827 次迭代中看到q值。或者 readThread 可以从第 100 次迭代开始时看到p值(即 p=100),但从该迭代结束时看到q值(即 q=101)。

于 2015-04-10T08:57:44.223 回答