java - 共享变量的旧值

标签 java multithreading

在阅读 Concurrency in practice 时,我读到:

NoVisibility demonstrated one of the ways that insufficiently synchronized programs can cause surprising results: stale data. When the reader thread examines ready, it may see an out of date value. Unless synchronization is used every time a variable is accessed, it is possible to see a stale value for that variable. Worse, staleness is not all or nothing: a thread can see an up-to-date value of one variable but a stale value of another variable that was written first.

public class NoVisibility {
    private static boolean ready;
    private static int number;

    private static class ReaderThread extends Thread {
        public void run() {
            while (!ready)
                Thread.yield();
            System.out.println(number);
        }
    }

    public static void main(String[] args) {
        new ReaderThread().start();
        number = 42;
        ready = true;
    }
}

我没有理解陈旧的意思。两个线程共享相同的引用,一个修改的值如何对另一个线程可见或不可见?

最佳答案

Each thread has its own stack, and so its own copy of variables it can access. When the thread is created, it copies the value of all accessible variables in its own memory. The volatile keyword is used to say to the jvm "Warning, this variable may be modified in an other Thread". Without this keyword the JVM is free to make some optimizations, like never refreshing those local copies in some threads. The volatile force the thread to update the original variable for each variable.

来源DZone

硬件实现

发生这种情况是由于为快速访问变量而进行的处理器优化。当变量保存在缓存中时,访问比每次访问内存要快得多。所以为了刷新缓存,你需要说 volatile 去刷新缓存并重建它,因为这个变量正在其他线程中被修改。

static 变量的缓存也已完成,由于同样的原因快速访问,它们也有资格进行缓存。所以是的,对于 static 变量,您也需要 volatile

另见:

What does volatile do?

关于java - 共享变量的旧值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20738642/

相关文章:

java - 计算随机数的出现次数

java - 强制我的 Activity 调用 onSaveInstanceState

java - 如何统计由System.lineSeparator()分隔的字符串的字数和行数?

java - 为什么将 "this"传递给 Thread 构造函数不安全?

c++ - std::forward_list.push_front(std::thread) 编译失败

c - 如何在 Mac OS X 上使用 C 实现协作轻量级线程?

java - 线程和静态方法

java - 如何从主 Activity 类中的自定义 ListView 适配器管理 onClick 函数

java - 如何从 2D int 数组构造 ArrayList?

c# - WCF服务的线程安全处置