如何证明未正确发布的值的竞争条件?

and*_*oot 9 java concurrency

我正在阅读"Java Concurrency in practice"并查看第51页的示例代码.

根据该书,如果没有正确发布,这段代码就有可能失败.因为我喜欢编写示例并打破它们来证明它们是如何工作的.我试图让它抛出AssertionError但失败了.(引导我回到上一个问题)

任何人都可以发布示例代码,以便抛出AssertionError吗?规则:不要修改Holder类.

public class Holder{
    private int n;

    public Holder(int n){
        this.n = n;
    }

    public void assertSanity(){
        if (n != n) {
            throw new AssertionError("This statement is false");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我修改了类以使其更脆弱但我仍然无法获得AssertionError.

class Holder2 {
    private int n;
    private int n2;

    public Holder2(int n) throws InterruptedException{
        this.n = n;
        Thread.sleep(200);
        this.n2 = n;
    }

    public void assertSanity(){
        if (n != n2) {
            throw new AssertionError("This statement is false");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

是否有可能使上述任何一个类抛出AssertionError?或者我们是否必须接受他们偶尔会这样做而且我们不能编写代码来证明它?

lee*_*roy 3

我会在多处理器机器上运行几个小时,看看会发生什么(如果您使用 Holder2,请删除睡眠)。这种竞争条件可能很少见,或者在您的特定机器上不存在 - 但至少尝试通过尝试数百万次来在一百万个案例中引发这些竞争条件。

class Checker {
  private Holder h;
  public Checker() {
   h = new Holder(42);
  }

  public void check() {
    h.assertSanity();
  }

  public void create(int n) {
   h = new Holder(n);
   }

}

public class MyThread extends thread{
  private bool check;
  private final Checker c;
  public MyThread(bool check,Checker c) {
    this.check = check;
    this.c = c;
  }
    public static void main(String[] args) {
      Checker c = new Checker();
      MyThread t1 = new MyThread(false,c);  
      MyThread t2 = new MyThread(true,c);
      t1.start();
      t2.start();
      t1.join();
      t2.join();
   }
   public void run() {
     int n = 0;
     while(true) {
       if(check) 
         c.check();
       else
         c.create(n++);
    }
   }
 }
}
Run Code Online (Sandbox Code Playgroud)