java - 由另一个线程在一个线程中设置变量

标签 java multithreading

为什么另一个线程调用的f()方法中的pool没有设置为5?

public class Main {        
        private static int pool = 5;        
        public static void main(String... arg) {        
            Th t = new Th();
            Thread thread = new Thread(t);
            thread.start();

            while (true) {        
               if (pool >= 0)
                    System.out.println(pool--);
            }       
        }

        static void f() {
            pool = 5;
            System.out.println("main.Main.f:pool=" + pool);
        }       
    }
    class Th implements Runnable {        
        @Override
        public void run() {
            while (true) {
                try {
                    TimeUnit.SECONDS.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                Main.f();        
            }
        }
    }

输出:

5
4
3
2
1
0
main.Main.f:pool=5
main.Main.f:pool=5
main.Main.f:pool=5
main.Main.f:pool=5

我可以修复它,将pool声明为 volatile ,但我不明白为什么它可以工作8(

最佳答案

一个线程写入的值并不总是能被另一个线程读取。为了保证可见性,需要有一个“内存屏障”,将字段声明为 volatile 是获得该保证的一种方法。

粗略地说,如果需要的话,您必须请求可见性,否则运行时可以作为优化而跳过它。例如,它可能使用寄存器来存储主线程的池值,而不是更新堆中对象的字段。您的代码并不表明其他线程应该能够区分差异,因此允许运行时执行优化。

关于java - 由另一个线程在一个线程中设置变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37283620/

相关文章:

python - Python 中的异步多线程抓取,线程有限

c++ - 在消息发送线程中使用std::condition_variable等待,发生死锁

java - 当 ActiveMQ 启动时警告为 java.io.EOFException

java - 在 Java 中使用 for 循环,是否必须指定 not null?

java - JAXB 无法加载名称包含 URL 编码字符的文件

java - 用于生成、转换和计数频率的线程

java - 如何通过实现Runnable接口(interface)来减少内存消耗?

java - 显示 struts 验证消息

java - 如何在Eclipse的Gradle项目中重命名包

在信号处理程序中创建线程