对于多个类的实例,Volatile关键字无法正常工作

use*_*070 2 java multithreading volatile

我已经阅读了几乎所有帖子中的volatile(即使它不是静态的)变量在线程之间共享.当一个线程更新变量时,第二个线程获取更新的值.但是当我在本地机器上运行代码时,运行java 7.它没有给出预期的结果

代码 -

public class StatciVolatile3 {

    public static void main(String args[]) {
        new ExampleThread2("Thread 1 ").start();
        new ExampleThread2("Thread 2 ").start();
    }

}

class ExampleThread2 extends Thread {
    private volatile int testValue = 1;

    public ExampleThread2(String str) {
        super(str);
    }

    public void run() {
        for (int i = 0; i < 3; i++) {
            try {
                System.out.println(getName() + " : " + i);
                if (getName().compareTo("Thread 1 ") == 0) {
                    testValue++;
                    System.out.println("Test Value T1: " + testValue);
                }
                if (getName().compareTo("Thread 2 ") == 0) {
                    System.out.println("Test Value T2: " + testValue);
                }
                Thread.sleep(1000);
            } catch (InterruptedException exception) {
                exception.printStackTrace();
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

结果是 -

Thread 2  : 0
Test Value T2: 1
Thread 1  : 0
Test Value T1: 2
Thread 2  : 1
Test Value T2: 1
Thread 1  : 1
Test Value T1: 3
Thread 2  : 2
Test Value T2: 1
Thread 1  : 2
Test Value T1: 4
Run Code Online (Sandbox Code Playgroud)

在这里,我们可以看到线程T2的测试值总是1.有人可以帮助我理解为什么会发生这种情况吗?

提前致谢!

我的预期结果是 - 这是线程都看到更新的值

Thread 1  : 0
Test Value T1: 2
Thread 2  : 0
Test Value T2: 2
Thread 1  : 1
Test Value T1: 3
Thread 2  : 1
Test Value T2: 3
Thread 1  : 2
Test Value T1: 4
Thread 2  : 2
Test Value T2: 4
Run Code Online (Sandbox Code Playgroud)

dav*_*mac 8

testValue是一个实例变量,因此每个类的实例都有一个单独的变量副本.您已经创建了两个实例:

   new ExampleThread("Thread 1 ").start();
   new ExampleThread("Thread 2 ").start();
Run Code Online (Sandbox Code Playgroud)

......每个人都有自己的变量副本.线程2永远不会更新其值,这就是它保持为1的原因.

如果您希望它们共享相同的变量,请将其设置为static:

private static volatile int testValue = 1;
Run Code Online (Sandbox Code Playgroud)

你的陈述:

我已经阅读了几乎所有帖子中的volatile(即使它不是静态的)变量在线程之间共享

...表明你对所读内容的误读或误解.如果线程之间访问同一个变量,则会在线程之间看到对volatile变量的更改,但这并不意味着实例之间将共享实例变量.

一些评论指出'testValue ++'不是原子操作.通常,您应该避免在线程之间共享的volatile变量上执行此类操作.但是,对于有限的示例,这实际上并不是一个问题,因为只有一个线程实际上会改变变量的值.

  • `如果你想让它们共享同一个变量,那就把它变成静态:`这是一个明显不正确的答案.操作`testValue ++`不是原子操作,标记`testvalue``static`不能解决问题 (2认同)