public class TestThread2 {
static int count = 0;
public static void main(String[] args) {
Thread t = new Thread(new Runnable(){
public void run()
{
for (int i=1; i<=100000; i++) {
count++;
}
}
});
Thread t1 = new Thread(new Runnable(){
public void run()
{
for (int i=1; i<=100000; i++) {
count++;
}
}
});
t.start();
t1.start();
try{
t.join();
t1.join();
}
catch(InterruptedException e){
e.printStackTrace();
}
System.out.println(count);
}
}
上面的代码打印了各种计数值,如131938,127518等。但我认为它应该总是打印20000,因为在调用join()之后,主线程无法移动到下一个语句,直到当前线程死亡。我知道我在这里错过了一个基本概念,但我无法弄清楚所以请帮忙。
答案 0 :(得分:2)
您没有同步变量。而不是static int count
,请使用AtomicInteger。
答案 1 :(得分:2)
i++
不是原子的。它有效:
int j = i;
i = j + 1;
如果两个线程同时尝试执行此操作,则来自不同线程的读取和写入可能会交错,这意味着该值在每个线程中都不会严格递增。
此外,无法保证一个线程的增加值对另一个线程可见。
不使用int
,而是使用AtomicInteger
和addAndGet
。 AtomicInteger
保证了增量的原子性和线程之间值的可见性。
static AtomicInteger count = new AtomicInteger();
// In the thread:
count.incrementAndGet();
请注意,the Oracle Java Tutorial中描述了与您的示例非常相似的内容。
答案 2 :(得分:1)
是join()
上的主要线程阻止。但是主线程没有写入变量count
,因此主线程正在做什么并不重要。您有2个线程t
和t1
,它们在没有任何同步的情况下读取和写入相同的变量count
,实际上它会导致不稳定的结果。