簡體   English   中英

多線程 - 為什么下面的程序表現得很奇怪?

[英]Multithreading - Why does the following program behave this weirdly?

該計划的大綱:
我們有兩個線程( t1t2 )寫一個整數值,然后將寫入的值刷新到RAM。
另一個線程( t3 )檢查該值是否與t1t2寫入的值一致,如果不符合,則打印它。

public class Container
{
     int a;
     volatile boolean b;


    public static void main(String[] args)
    {
        Container container = new Container();

        Thread t1 = new Thread()
        {
            @Override
            public void run()
            {
                for (;;)
                {
                    container.a = 409;
                    container.b ^= container.b;

                }
            }
        };

        Thread t2 = new Thread()
        {
            @Override
            public void run()
            {
                for (;;)
                {
                    container.a = 102;
                    container.b ^= container.b;
                }
            }
        };

        Thread t3 = new Thread()
        {
            @Override
            public void run()
            {
                try
                {
                    Thread.sleep(100);
                } catch (InterruptedException e)
                {
                    e.printStackTrace();
                }
                for (;;)
                {
                    if (container.a != 409 && container.a != 102 )
                        System.out.println(container.a);
                }
            }
        };

        t1.start();
        t2.start();
        t3.start();
    }
}

我認為會發生什么:
由於a volatile ,我認為t3會緩存a而且永遠不會打印任何東西。

實際發生了什么:
大約一秒左右(無論你多久t3睡覺),它會快速連續打印102或409.然后,打印停止(永久)。

這到底發生了什么?

container.a不是volatile,並不意味着它被t3強制緩存。 這意味着無論是否存在都無法保證。

可以自由打印任何值的原因是此處的使用時間檢查問題:

if (container.a != 409 && container.a != 102 )
   System.out.println(container.a);

至於為什么在你測試它的確切環境中的這種確切行為,我們只能猜測。 但是我的理由是,雖然代碼是按解釋的方式運行的,但它每次都會讀取container.a .a,但一旦它被Hotspot編譯為本機代碼,該值只被加載到寄存器中一次,那就是結束了。 您可以使用-XX:+PrintCompilation命令行標志來驗證此假設。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM