为什么重入锁在演示中同步工作时不起作用?

我正在尝试遵循Java中的重入锁示例,同步与重入锁之间的区别类型的教程。我有一个演示开始于-ea


public class ReentrantLockZero {

    private static ReentrantLock CountLock = new ReentrantLock();

    private static int count = 0;

    private static final int RESULT_COUNT = 10_000;


    public static void main(String... args) throws Exception {

        ThreadPoolExecutor threadPoolExecutor = getMyCachedThreadPool();

        for (int i = 0; i < RESULT_COUNT; ++i) {

            threadPoolExecutor.submit(ReentrantLockZero::getCount);

            threadPoolExecutor.submit(ReentrantLockZero::getCountUsingLock);

        }

        threadPoolExecutor.shutdown();

        threadPoolExecutor.awaitTermination(10, TimeUnit.SECONDS);

        assert count == RESULT_COUNT * 2;

    }


    private static synchronized int getCount() {

        count++;

        System.out.println(Thread.currentThread().getName() + " counting in synchronized: " + count);

        return count;

    }


    private static int getCountUsingLock() {

        CountLock.lock();

        try {

            count++;

            System.out.println(Thread.currentThread().getName() + " counting in lock: " + count);

            return count;

        } finally {

            CountLock.unlock();

        }

    }

}

当使用作为第二种方法时,我会得到,但是当我注释它们使用时,那就没关系了。ReentrantLockgetCountUsingLockjava.lang.AssertionErrorsynchronized


考虑到它的 Reententlock,我删除了类中定义的,并使用本地锁,如下所示,但它仍然不起作用。CountLock


private static int getCountUsingLock() {

    ReentrantLock countLock = new ReentrantLock();

    countLock.lock();

    try {

        count++;

        System.out.println(Thread.currentThread().getName() + " counting in lock: " + count);

        return count;

    } finally {

        countLock.unlock();

    }

}

这里遗漏的要点是什么?


任何帮助将不胜感激;)


摇曳的蔷薇
浏览 111回答 1
1回答

Cats萌萌

有点傻自己。它就是这样工作的,因为我实际上锁定了不同的对象。private static synchronized int getCount()等于private static synchronized (ReentrantLockZero.class) int getCount()而始终是一个新对象,并且无法使用不同的锁来消除争用条件。new ReentrantLock();所以傻瓜我,它很容易通过以下演示修复public class ReentrantLockZero {&nbsp; &nbsp; private static ReentrantLock CountLock = new ReentrantLock();&nbsp; &nbsp; private static int synchronisedCount = 0;&nbsp; &nbsp; private static int lockedCount = 0;&nbsp; &nbsp; private static final int RESULT_COUNT = 10_000;&nbsp; &nbsp; public static void main(String... args) throws Exception {&nbsp; &nbsp; &nbsp; &nbsp; ThreadPoolExecutor threadPoolExecutor = getMyCachedThreadPool();&nbsp; &nbsp; &nbsp; &nbsp; for (int i = 0; i < RESULT_COUNT; ++i) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; threadPoolExecutor.submit(ReentrantLockZero::getSynchronisedCount);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; threadPoolExecutor.submit(ReentrantLockZero::getCountUsingLock);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; threadPoolExecutor.shutdown();&nbsp; &nbsp; &nbsp; &nbsp; threadPoolExecutor.awaitTermination(10, TimeUnit.SECONDS);&nbsp; &nbsp; &nbsp; &nbsp; assert synchronisedCount == RESULT_COUNT;&nbsp; &nbsp; &nbsp; &nbsp; assert lockedCount == RESULT_COUNT;&nbsp; &nbsp; }&nbsp; &nbsp; private static synchronized int getSynchronisedCount() {&nbsp; &nbsp; &nbsp; &nbsp; synchronisedCount++;&nbsp; &nbsp; &nbsp; &nbsp; System.out.println(Thread.currentThread().getName() + " counting in synchronized: " + synchronisedCount);&nbsp; &nbsp; &nbsp; &nbsp; return synchronisedCount;&nbsp; &nbsp; }&nbsp; &nbsp; private static int getCountUsingLock() {&nbsp; &nbsp; &nbsp; &nbsp; CountLock.lock();&nbsp; &nbsp; &nbsp; &nbsp; try {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; lockedCount++;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; System.out.println(Thread.currentThread().getName() + " counting in lock: " + lockedCount);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return lockedCount;&nbsp; &nbsp; &nbsp; &nbsp; } finally {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; CountLock.unlock();&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}为什么工作?因为那时只有一个锁,所以两种方法都锁定了,所以直接解决了争用条件。synchronized
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java