java - 核心 Java 线程和 Volatile 关键字用法

标签 java multithreading synchronization volatile

我最近开始研究核心 Java 中的多线程。我正在研究一个 Volatile 关键字。根据我的理解,允许线程在本地保留变量的值。如果变量正在驱动任何逻辑(例如循环),那么线程将看不到变量的更改,并且它们将继续使用过时的缓存值,除非变量声明为“volatile”。

我创建了一个小代码来演示这一点,但是,我的观察结果有所不同。一个线程(主线程)所做的更改对另一个线程非常可见,即使共享变量“完成”不是易变的。谁能帮我理解这种行为

package com.test;

public class App implements Runnable {
    private boolean done= true;
    private static App a = new App();   


    public static void main( String[] args ) throws InterruptedException {
        Thread t = new Thread(a);
        t.start();
        System.out.println("Main Thread:"+ Thread.currentThread().getName());
        Thread.sleep(1);
        a.done=false;
        System.out.println("Value of done in main method is:"+ a.done);
    }

    public void run() {
        while(done) {
             System.out.println("Second Thread:"+ Thread.currentThread().getName());
            System.out.println("Still running");
        }
    }
}

以上代码输出结果如下

Main Thread:main
Second Thread:Thread-0
Still running
Second Thread:Thread-0
Still running
Second Thread:Thread-0
Still running
Second Thread:Thread-0
Still running
Second Thread:Thread-0
Still running
Second Thread:Thread-0
Still running
Value of done in main method is:false

最佳答案

关键字 volatile 保证了您描述的行为。 volatile 字段的值在 write 操作后对所有读者可见。这意味着没有使用缓存值。

如果您没有使用 volatile 关键字,这并不意味着您总是在使用旧的缓存变量。这只是这种可能发生的可能性。


要点:

您使用 volatile 关键字来保证 内存可见性。这并不意味着不使用它会在您使用多线程时立即破坏您的代码。


另请注意,volatile 不保证与您的变量进行原子交互。这意味着 volatile 字段在竞争条件和其他潜在问题方面不会自动成为线程安全的。

关于java - 核心 Java 线程和 Volatile 关键字用法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49405905/

相关文章:

python - 如何正确确保使用共享锁的线程终止?

c# - Exchange EWS 文件夹同步仅获取编程更改

java - 减少 Java 中同步块(synchronized block)的范围意外地损坏了我的 ArrayList,为什么会出现这种情况?

java - 带窗口的 KTable 会产生错误的类型

android - 从非 UI 线程更新 View

windows - 我应该为 RTSP 客户端创建一个新线程还是只使用媒体基础中的自定义 IMFMediaSource

android - 以编程方式在 Android 中添加日历事件不会同步到网络

java - 尝试在 websphere 8.5.5.13 上部署 Ear 时出现 AnnotationException?

java - 如何在 Spring 引导分页中返回 DTO 而不是实体?

java - 更改 Spring 应用程序启动消息