簡體   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