在另一个线程中设置变量

时间:2016-05-17 18:21:25

标签: java multithreading

为什么pool在另一个线程调用的f()方法中没有设置为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(

2 个答案:

答案 0 :(得分:2)

一个线程写入的值不会被另一个线程读取。需要有一个记忆障碍"为了保证可见性,并将字段声明为volatile是获得该保证的一种方式。

简而言之,如果需要,您必须要求可见性,否则运行时可以自由跳过它作为优化。例如,它可能使用寄存器来存储主线程的pool值,而不是更新堆中对象的字段。您的代码并不表示其他线程应该能够区分,因此允许运行时执行优化。

答案 1 :(得分:0)

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