简体   繁体   English

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

[英]Why ReentrantLock is not working while synchronized work in the demo?

I am trying to follow the ReentrantLock Example in Java, Difference between synchronized vs ReentrantLock kind of tutorial. 我正在尝试遵循Java中ReentrantLock示例,同步与ReentrantLock之类的教程之间的区别 And I have a demo started with -ea on as 我有一个以-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();
        }
    }
}

When using ReentrantLock as the second method getCountUsingLock , I will get java.lang.AssertionError but when I commented them out to use synchronized , it would be okay. 当使用ReentrantLock作为第二种方法getCountUsingLock ,我将得到java.lang.AssertionError但是当我注释掉它们以使用synchronized ,这将是可以的。

Considering its Re entrantLock, I removed the CountLock defined in the class and using local lock as following, but it still not work. 考虑到其重新 entrantLock,我删除了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();
    }
}

What's the missed point here? 这里错过了什么?

Any help will be appreciated ;) 任何帮助将不胜感激 ;)

Kind of fool of myself. 有点愚蠢。

It's working like that because I was actually locking on different objects . 之所以这样工作是因为我实际上是在锁定不同的对象

private static synchronized int getCount()

is equal to 等于

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

while new ReentrantLock(); new ReentrantLock(); is always a new object and there is no way to eliminate the race condition using different locks. 始终是一个新对象,无法使用不同的锁消除竞争状态

So fool of me, it's easily fixed by the following demos 真是我的傻瓜,可以通过以下演示轻松修复

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();
        }
    }
}

Why the synchronized work? 为什么要synchronized工作? Because then there is only one lock the two methods are locking on so the race condition resolved directly. 因为那时只有一个锁,所以这两种方法都处于锁定状态,因此竞争条件可以直接解决。

Kind of easily fooled by the tutorial; 有点容易被本教程所愚弄; shame on me ;( 对我感到羞耻;(

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM