[英]Multithreading - Why does the following program behave this weirdly?
該計划的大綱:
我們有兩個線程( t1
和t2
)寫一個整數值,然后將寫入的值刷新到RAM。
另一個線程( t3
)檢查該值是否與t1
或t2
寫入的值一致,如果不符合,則打印它。
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.