gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-30 01:52:59 24 4
gpt4 key购买 nike

我正在尝试遵循ReentrantLock Example in Java, Difference between synchronized vs ReentrantLock一种教程。我有一个以 -ea on as

开始的演示
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();
}
}

这里遗漏了什么?

任何帮助将不胜感激;)

最佳答案

我自己真是个傻瓜。

它的工作原理是这样的,因为我实际上锁定了不同的对象

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

为什么同步有效?因为这样两个方法只锁定一个锁,所以竞争条件直接解决。

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

关于java - 为什么演示中同步工作时 ReentrantLock 不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55428346/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com