Why is synchronized not working properly?

前端 未结 5 591
渐次进展
渐次进展 2020-12-11 06:55

Here\'s my code:

private int count = 0;

  public synchronized void increment() {
      count++;
  }

 public void doWork() throws InterruptedException {

          


        
5条回答
  •  情深已故
    2020-12-11 07:56

    The increment method can be run on the other thread after the increment method returns, but before count is retrieved for the concatenation

    count+"  "+Thread.currentThread().getName()
    

    You could e.g. fix this by modifying and retrieving count in one synchronized block:

    public synchronized int incrementAndGet() {
        count++;
        return count; // read access synchronized
    }
    
    for (int i = 0; i < 5; i++) {
        System.out.println(incrementAndGet()+"  "+Thread.currentThread().getName());
    }
    

    Or use the class in the standard library specifically designed for this purpose:

    private final AtomicInteger counter = new AtomicInteger(0);
    
    public void doWork() throws InterruptedException {
    
        Thread t1 = new Thread(new Runnable() {
            public void run() {
                for (int i = 0; i < 5; i++) {
                    System.out.println(counter.incrementAndGet() + "  " + Thread.currentThread().getName());
                }
            }
        });
    
        Thread t2 = new Thread(new Runnable() {
            public void run() {
                for (int i = 0; i < 5; i++) {
                    System.out.println(counter.incrementAndGet() + "  " + Thread.currentThread().getName());
                }
            }
        });
    
        t1.start();
        t2.start();
    }
    

    Of course this does not necessarily lead the numbers 1 to 10 being printed in order, just that no number is retrieved more than once. The following output could happen:

    2  Thread-0
    3  Thread-0
    4  Thread-0
    1  Thread-1
    5  Thread-0
    6  Thread-1
    7  Thread-0
    8  Thread-1
    9  Thread-1
    10  Thread-1
    

提交回复
热议问题