我有一个最喜欢的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