我有一個最喜歡的C#程序類似於下面的那個,表明如果兩個線程共享相同的內存地址進行計數(一次線程遞增n次,一次線程遞減n次),您可以獲得非零的最終結果。只要n相當大,就很容易讓C#在[-n,n]之間顯示一個非零值。但是,即使將線程數增加到1000個(500個,500個),我也無法讓Java產生非零結果。有沒有一些內存模型或規格差異與C#我不知道,保證這個程序將始終屈服0儘管我沒有意識到的核心的調度或數量?我們是否同意,即使我們無法通過實驗證明,該計劃也能產生非零價值?這個Java程序可以打印非零值嗎?
(不:,我發現這個問題詢問過here,但是當我運行該主題的代碼我也得到零。)
public class Counter
{
private int _counter = 0;
Counter() throws Exception
{
final int limit = Integer.MAX_VALUE;
Thread add = new Thread()
{
public void run()
{
for(int i = 0; i<limit; i++)
{
_counter++;
}
}
};
Thread sub = new Thread()
{
public void run()
{
for(int i = 0; i<limit; i++)
{
_counter--;
}
}
};
add.run();
sub.run();
add.join();
sub.join();
System.out.println(_counter);
}
public static void main(String[] args) throws Exception
{
new Counter();
}
}
我猜你的意思是調用''開始的(),而不是'的run()',否則,你有沒有額外的線程在所有。 – Progman
有時候我真的不明白當我的一個程序運行時Java VM內部發生了什麼。 JRE執行多次優化,在這種情況下,可以通過最終的「合併」操作對每個線程中分配給整數的值進行緩存(如變量「產卵」爲多個副本),或者是誰知道......也許線程不是「本地」的線程。我們應該看看你的平臺的JRE代碼:) – gd1
哦,親愛的,只是共同的開始<>運行混亂? – gd1