繁体   English   中英

在另一个线程中设置变量

[英]Setting variable in one thread by another

为什么在另一个线程调用的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

我可以修复它声明poolvolatile但是我不知道为什么它可以工作8(

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

松散地说,您必须询问是否需要可见性,否则运行时可以自由跳过它以进行优化。 例如,它可能使用寄存器来存储主线程的pool值,而不是在堆中更新对象中的字段。 您的代码没有表明其他线程应该能够区分出差异,因此允许运行时执行优化。

该行为是有道理的:您的main()中没有sleep() -因此它能够快速连续执行五次减量。 然后在1000毫秒后f()之后每隔一秒f()调用f()以将池设置为5。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM