java - 对于一个类的多个实例,Volatile 关键字无法按预期工作

标签 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();
            }
        }
    }
}

结果是 -

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

正如我们所见,线程 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

最佳答案

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

   new ExampleThread("Thread 1 ").start();
   new ExampleThread("Thread 2 ").start();

...并且每个都有自己的变量副本。线程 2 从不更新其值,这就是它保持为 1 的原因。

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

private static volatile int testValue = 1;

您的声明:

I have read in almost all the posts that volatile (even if it's not static) variable is shared among the the threads

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

一些评论指出“testValue++”不是原子操作。一般来说,您确实应该避免对在线程之间共享的 volatile 变量进行此类操作。然而,对于您有限的示例,这实际上并不是一个问题,因为只有一个线程实际上会改变变量的值。

关于java - 对于一个类的多个实例,Volatile 关键字无法按预期工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30642042/

相关文章:

java - 显示 netbeans JTable 中链接表的数据

Java:函数可以返回调用类和方法名称的任何简单方法?

java - 如果当前线程有权限退出Java虚拟机

c++ - `static_cast<volatile void>` 对优化器意味着什么?

java - 在 Eclipse 中使用固定的 java 交换 Maven 依赖项中的类文件

java - 保存到 Oracle 表时 Blob 被截断

Python:进程/线程监控

c++ - boost asio http服务器,如何停止?

java - volatile 变量是否需要同步访问?

java - volatile 数组 - 元素的内存可见性