您可以复制粘贴以下示例以在本地计算机上运行。我正在学习MultiThreading,并且在网上遇到了这个示例。我对为什么方法add(inside class Counter)如果声明为sync会有所不同感到困惑,您可以从中删除sync的关键字,并且不会影响最终结果,所以我只是想知道该服务的目的是什么宣布它已同步

class Counter {

    long count = 0;

    public synchronized void add(long value) {
        this.count += value;
        System.out.println(count + "-" + Thread.currentThread().getName());
    }
}

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++) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException ex) {
                Logger.getLogger(CounterThread.class.getName()).log(Level.SEVERE, null, ex);
            }
            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);
        Thread threadC = new CounterThread(counter);

        threadA.start();
        threadB.start();
        threadC.start();
    }
}

最佳答案

关键字synchronized可防止threadA,threadB和threadC同时执行操作。重要的是要了解this.count += value在内部实现为三个操作:

  • 读取计数字段
  • 添加值
  • 写计数字段

  • 如果删除synchronized关键字,那么可以想象以下事件序列:
  • 线程A读取计数字段(0)
  • threadB读取计数字段(0)
  • 线程A将值添加到计数(例如,从#1计数= 0 +值= 1)
  • threadB将值添加到计数(例如#2中的count = 0 + value = 1)
  • 线程A写入计数字段(#3中的1)
  • threadB写计数字段(#4中的1(!),因此丢失了#5中的写操作)
  • 关于java - 在下面的示例中声明一个同步方法的目的是什么,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/27560051/

    10-08 21:22