了解Java

时间:2018-03-05 16:43:16

标签: java multithreading

我正在阅读此链接。 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将加入。

我的理解是否正确,输出也可能因线程而异,或者我错过了一些概念。

1 个答案:

答案 0 :(得分:0)

每当你的一个线程绕过它的循环时,它会释放锁定,然后立即尝试再次锁定它。

您的系统上看起来,锁定机制没有&#34;公平&#34;对它来说,刚刚释放锁的线程能够在另一个线程知道它被释放之前再次抓取它。

它可能在其他系统上表现不同。但话说回来,你永远不会知道。

如果您想尝试@Zabuza建议的内容,请更改您的run()方法,

public void run() {
    for(int i=0; i<10; i++){
        counter.add(i);
        Thread.sleep(10);
    }
 }

睡眠调用会让另一个线程有机会醒来并抓住锁定。