这个多线程同步代码有什么问题?

时间:2015-09-22 02:47:29

标签: java multithreading

public class Counting {
    public static void main(String[] args) throws InterruptedException {
        class Counter {
            private int count = 0;

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

            public int getCount() {
                return count;
            }
        }
        final Counter counter = new Counter();
        class CountingThread extends Thread {
            public void run() {
                for (int x = 0; x < 10000; ++x)
                    counter.increment();
            }
        }
        CountingThread t1 = new CountingThread();
        CountingThread t2 = new CountingThread();
        t1.start();
        t2.start();
        t1.join();
        t2.join();
        System.out.println(counter.getCount());
    }
}

我正在阅读关于并发性的教科书,我对此示例感到困惑。在这里,我有许多线程共享的计数器类。由于在增量方法中会有竞争条件,我们使它同步,因此一次只有一个线程访问它。但是,根据该书,方法getCount()也应该同步。我无法理解为什么会这样?如果getCount未同步,将会发生什么问题?

编辑:该书说,如果不同步getCount,我们可能会看到过时的数据。

1 个答案:

答案 0 :(得分:2)

本书错误在示例代码的上下文中,因为getCount仅在主线程加入线程which ensure a happens-before.之后访问 p>

  

当一个线程终止并导致另一个线程中的Thread.join返回时,终止线程执行的所有语句与成功连接后的所有语句都有一个先发生的关系。现在,执行连接的线程可以看到线程中代码的效果。

然而,使getCount同步 - 虽然在原子get-and-increment-if中仍然没用 - 将确保在某些其他情况下的可见性,而不会发生先发生的保证。如果没有发生 - 之前保证会返回“陈旧”值 ,但这也不能保证。