我正在阅读此链接。 http://tutorials.jenkov.com/java-concurrency/synchronized.html
示例是:
public class Counter{
long count = 0;
public synchronized void add(long value){
this.count += value;
System.out.println("Thread="+Thread.currentThread().getId()+"value ="+count);
}
}
public 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 Jenkov2 {
public static void main(String[] args){
Counter counter = new Counter();
Thread threadA = new CounterThread(counter);
Thread threadB = new CounterThread(counter);
threadA.start();
threadB.start();
}
}
在我的系统上运行时,它总是提供固定输出。
Thread=9value =0
Thread=9value =1
Thread=9value =3
Thread=9value =6
Thread=9value =10
Thread=9value =15
Thread=9value =21
Thread=9value =28
Thread=9value =36
Thread=9value =45
Thread=10value =45
Thread=10value =46
Thread=10value =48
Thread=10value =51
Thread=10value =55
Thread=10value =60
Thread=10value =66
Thread=10value =73
Thread=10value =81
Thread=10value =90
我多次运行但输出始终相同。 我期待它在两个线程之间切换,两个线程完成后值将为90。 按照我的说法,它会是这样的: thread一个run方法被调用,i是0,0将被添加,并且当方法被同步时,它将在添加零之后返回,然后在i for inside for循环的下一次迭代之前,可能发生上下文切换并且线程B运行并且值0将加入。
我的理解是否正确,输出也可能因线程而异,或者我错过了一些概念。
答案 0 :(得分:0)
每当你的一个线程绕过它的循环时,它会释放锁定,然后立即尝试再次锁定它。
在您的系统上看起来,锁定机制没有&#34;公平&#34;对它来说,刚刚释放锁的线程能够在另一个线程知道它被释放之前再次抓取它。
它可能在其他系统上表现不同。但话说回来,你永远不会知道。
如果您想尝试@Zabuza建议的内容,请更改您的run()
方法,
public void run() {
for(int i=0; i<10; i++){
counter.add(i);
Thread.sleep(10);
}
}
睡眠调用会让另一个线程有机会醒来并抓住锁定。