Java 为什么我的两个线程可以通过非易失性字段进行协调?

Java 为什么我的两个线程可以通过非易失性字段进行协调?,java,multithreading,volatile,Java,Multithreading,Volatile,根据,两个java线程不能通过非易失性字段进行协调。为什么我的代码运行正常 public class TestVolatileExample { static int pairCount = 1000; static VolatileExample[] exps = new VolatileExample[pairCount]; static{ for(int i = 0;i<pairCount;i++){ exps[i] = new VolatileExampl

根据,两个java线程不能通过非易失性字段进行协调。为什么我的代码运行正常

public class TestVolatileExample {

static int pairCount = 1000;
static VolatileExample[] exps = new VolatileExample[pairCount];
static{
    for(int i = 0;i<pairCount;i++){
        exps[i] = new VolatileExample();
    }
}

@Test
public void test() throws InterruptedException{
    final int valuePair[][] = new int[pairCount][2];
    Thread[] threads = new Thread[pairCount*2];
    for(int i = 0;i<pairCount;i++){
        final int index = i;
        //final VolatileExample exp = new VolatileExample();
        //writer
        Thread writer = new Thread(new Runnable(){
            @Override
            public void run() {
                VolatileExample exp = exps[index];
                int val = new Random().nextInt(100);
                valuePair[index][0] = val;
                exp.set(val);
            }
        });
        writer.start();
        threads[i*2] = writer;
        //reader
        Thread reader = new Thread(new Runnable(){
            @Override
            public void run() {
                VolatileExample exp = exps[index];
                while(!exp.changed()){
                    try {
                        Thread.sleep(1);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    //System.out.println("waitting for change...");
                }
                int val = exp.get();
                valuePair[index][1] = val;
            }

        });
        reader.start();
        threads[i*2+1] = reader;
    }
    for(Thread t : threads){
        t.join();
    }
    for(int i = 0;i<pairCount;i++){
        int write = valuePair[i][0];
        int read =  valuePair[i][1];
        System.out.println(write+"," + read);
        Assert.assertEquals(write,read);
    }
 }
}
public class VolatileExample {

  private int x;
  private boolean changed = false; 

  public void set(int x){
      this.x = x;
      this.changed = true;
      System.out.println("changed...");
  }

  public int get(){
      return x;
  }

  public boolean changed(){
      return changed;
  }
}
公共类TestVolatileExample{
静态整数对计数=1000;
静态VolatileExample[]exps=新VolatileExample[pairCount];
静止的{

对于(int i=0;i,您链接到的页面显示:

编译器可以自由读取此字段。只需执行一次,然后重新使用 循环每次执行中的缓存值。这意味着 即使另一个线程更改了循环,循环也永远不会终止 这个的价值。完成

这意味着你的代码是否有效取决于编译器是否决定缓存你的变量(不起作用)或者不起作用


因此,您的代码可能工作,也可能不工作,这取决于您无法控制的内容。

非易失性属性
已更改
可以根据规范保存在线程缓存中,但不能保证。两个java线程无法通过非易失性字段进行协调,具体取决于您是否具有未定义的行为,因为访问to共享变量是不同步的。根据平台的不同,它可能有时起作用,有时不起作用。这句话应该是:
两个java线程不应通过非易失性字段协调。
。它可能10次工作9次,但不能保证成功。Re,“…将保存在每个线程各自的缓存中…”缓存不是“保存”东西的地方。它是允许线程共享内存的硬件和软件系统的实现细节。在Java语言规范(JLS)中甚至找不到“缓存”一词。您将发现有关如何使用
同步
易失性
以及各种“并发”类的规则。JLS承诺如果您遵守规则,系统将如何运行,但它不会承诺如果您违反规则会发生什么。