【问题标题】:Why ReentrantLock is not working while synchronized work in the demo?为什么在演示中同步工作时 ReentrantLock 不起作用?
【发布时间】:2019-03-30 05:03:54
【问题描述】:

我正在尝试遵循ReentrantLock Example in Java, Difference between synchronized vs ReentrantLock 类型的教程。我有一个以-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();
        }
    }
}

当使用ReentrantLock 作为第二种方法getCountUsingLock 时,我会得到java.lang.AssertionError,但是当我将它们注释掉以使用synchronized 时,就可以了。

考虑到它的ReentrantLock,我删除了类中定义的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();
    }
}

这里遗漏了什么?

任何帮助将不胜感激;)

【问题讨论】:

    标签: java java-8 synchronized reentrantlock


    【解决方案1】:

    有点自欺欺人。

    之所以如此,是因为我实际上是在锁定不同的对象

    private static synchronized int getCount()
    

    等于

    private static synchronized (ReentrantLockZero.class) int getCount()
    

    虽然new ReentrantLock(); 始终是一个新对象,并且没有办法使用不同的锁来消除race condition

    我太傻了,下面的演示很容易解决

    public class ReentrantLockZero {
        private static ReentrantLock CountLock = new ReentrantLock();
        private static int synchronisedCount = 0;
        private static int lockedCount = 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::getSynchronisedCount);
                threadPoolExecutor.submit(ReentrantLockZero::getCountUsingLock);
            }
            threadPoolExecutor.shutdown();
            threadPoolExecutor.awaitTermination(10, TimeUnit.SECONDS);
            assert synchronisedCount == RESULT_COUNT;
            assert lockedCount == RESULT_COUNT;
        }
    
        private static synchronized int getSynchronisedCount() {
            synchronisedCount++;
            System.out.println(Thread.currentThread().getName() + " counting in synchronized: " + synchronisedCount);
            return synchronisedCount;
        }
    
        private static int getCountUsingLock() {
            CountLock.lock();
            try {
                lockedCount++;
                System.out.println(Thread.currentThread().getName() + " counting in lock: " + lockedCount);
                return lockedCount;
            } finally {
                CountLock.unlock();
            }
        }
    }
    

    为什么synchronized 有效?因为那时只有一个锁,这两种方法都在锁定,所以竞争条件直接解决了。

    有点容易被教程愚弄;真丢脸;(

    【讨论】:

    • “有点像我自己”,就像我们一样。它被称为编程(0:
    • 谢谢你,c0der。周末愉快;)
    猜你喜欢
    • 1970-01-01
    • 2014-05-15
    • 1970-01-01
    • 1970-01-01
    • 2022-01-13
    • 1970-01-01
    • 1970-01-01
    • 2019-01-09
    • 2015-05-29
    相关资源
    最近更新 更多