因此,在进行一些工作面试后,我想编写一个小程序来检查在Java中
因此,我编写了这个程序来进行检查。
问题在于它挂起了。似乎主线程在
我发现如果:
i++
是否真的是非原子性的,并且应该在实践中添加一些锁来保护它。结果发现确实需要这样做,但这不是问题所在。因此,我编写了这个程序来进行检查。
问题在于它挂起了。似乎主线程在
t1.join()
行上卡住了,尽管由于前一行的stop=true
,两个工作线程都应该完成。我发现如果:
- 我在工作线程内部添加一些打印(如注释中所示),可能会导致工作线程有时放弃CPU。
- 如果我将标志
boolean stop
标记为volatile
,则会立即看到对工作线程的写入。 - 如果我将计数器
t
标记为volatile
...对于这一点,我不知道是什么原因导致了挂起。
public class Test {
static /* volatile */ long t = 0;
static long[] counters = new long[2];
static /* volatile */ boolean stop = false;
static Object o = new Object();
public static void main(String[] args)
{
Thread t1 = createThread(0);
Thread t2 = createThread(1);
t1.start();
t2.start();
Thread.sleep(1000);
stop = true;
t1.join();
t2.join();
System.out.println("counter : " + t + " counters : " + counters[0] + ", " + counters[1] + " (sum : " + (counters[0] + counters[1]) + ")");
}
private static Thread createThread(final int i)
{
Thread thread = new Thread() {
public void run() {
while (!stop)
{
// synchronized (o) {
t++;
// }
// if (counters[i] % 1000000 == 0)
// {
// System.out.println(i + ")" + counters[i]);
// }
counters[i]++;
}
};
};
return thread;
}
}