有人可以告诉我为什么以下代码不是线程安全的?我得到的输出是0或45或90.共享资源计数器有一个同步方法,所以我一直期望90输出。我在这里错过了什么吗?请指教。 请告诉我如何使这些代码线程安全。
class Counter{
long count = 0;
public synchronized void add(long value){
this.count += value;
}
}
class CounterThread extends Thread{
protected Counter counter = null;
public CounterThread(Counter counter){
this.counter = counter;
}
public void run() {
for(int i=0; i<10; i++){
counter.add(i);
}
}
}
public class Example {
public static void main(String[] args){
Counter counter = new Counter();
Thread threadA = new CounterThread(counter);
Thread threadB = new CounterThread(counter);
threadA.start();
threadB.start();
System.out.println(counter.count);
}
}
答案 0 :(得分:12)
等待线程完成。添加
threadA.join();
threadB.join();
在打印结果之前。
答案 1 :(得分:6)
答案 2 :(得分:3)
在线程停止之前,您不必等待println。因此,当for循环仍在进行时,您打印出计数器的值。它不需要对线程安全做任何事情。
答案 3 :(得分:2)
Counter
访问是线程安全的,但System.out.println(counter.count);
可以在其他线程完成其工作之前发生。
答案 4 :(得分:1)
您的代码是线程安全的,但更好的方法是摆脱同步方法并使用AtomicLong 并使用getAndAdd(long)方法
public final long getAndAdd(long delta)
>Atomically add the given value to current value.
答案 5 :(得分:0)
你有3个线程在那里运行。分配给变量threadA
的分配给threadB
和主线程的分配。
只要main
方法运行,主线程就会运行。其他2个启动并与主线程同时运行。但是,主线程没有被阻塞等待其他2完成,因此它在有机会执行时打印结果。