在实现的 java 代码中需要有关易失性和非易失性概念的帮助?

Need help in volatile and non volatile concept in implemented java code?

我写了下面的代码来理解 java 中的 volatile 概念,但输出似乎令人困惑,而不是澄清这个概念。欢迎和赞赏更正、澄清和反馈。

package threading;

public class UnSyncRead {
    //volatile static int value = 987;
    static int value = 987;
    public static void main(String[] args) {


        ThreadEx4 t = new ThreadEx4(value);
        t.start();
        for(int i=0;i<4;i++) {
            Thread thread = new Thread( new ThreadEx3(value));
            thread.start();
        }
    }

}

class ThreadEx3 implements Runnable{
private int i;
    public ThreadEx3(int i) {
        this.i=i;
}

    @Override
    public void run() {
        System.out.println(Thread.currentThread().getId()+ "  "+Thread.currentThread().getName()+" "+ " inside "+i);
    }



}

class ThreadEx4 extends Thread{
    private int i;
    public ThreadEx4(int i) {
        this.i=i;
    }
    public void run() {
        ++i;
        System.out.println("changed the value to "+i);
    }
}

该程序给出以下输出

changed the value to 988
12  Thread-1  inside 987
13  Thread-2  inside 987
14  Thread-3  inside 987
15  Thread-4  inside 987

但是如果我通过以下更改和 运行 代码来修改代码以使 value 成为变量 volatile

public class UnSyncRead {
volatile static int value = 987;
//static int value = 987;
public static void main(String[] args) {


    ThreadEx4 t = new ThreadEx4(value);
    t.start();
    for(int i=0;i<4;i++) {
        Thread thread = new Thread( new ThreadEx3(value));
        thread.start();
    }
}

}

我得到以下输出,这与我 运行 没有使用 volatile 关键字时完全相同。

changed the value to 988
12  Thread-1  inside 987 
13  Thread-2  inside 987
14  Thread-3  inside 987
15  Thread-4  inside 987 

我的问题是为什么 for 循环中的线程仍然读取 value 变量的值作为 987 而不是 988,即使在实现 volatile 关键字之后也是如此。

非常感谢对这个问题的回答。

这与多线程完全无关,这是一个更基本的问题。

class ThreadEx4 extends Thread{
    private int i;
    public ThreadEx4(int i) {
        this.i=i;
    }
    public void run() {
        ++i;
        System.out.println("changed the value to "+i);
    }
}

您正在此处更改您的私有变量 i,而不是全局 static 字段。

Java 按值传递事物。所以当你说 new ThreadEx4(myInteger) 时,构造函数将收到 myInteger 内的数字。它对其本地副本所做的任何操作都不会影响 myInteger

要继续您的 multi-threading 实验,请删除局部变量并执行

class Ex4 extends Runnable {
      @Override
      public void run(){
          int newValue = ++UnSyncRead.value;
          System.out.println("changed the value to "+newValue);
      }
}
// and the same for the other runnables