Вид дурака из себя.
Это работает так, потому что я на самом деле блокирую разные объекты .
private static synchronized int getCount()
равно
private static synchronized (ReentrantLockZero.class) int getCount()
, в то время как new ReentrantLock();
всегда является новым объектом, и невозможно устранить условие гонки , используя различные блокировки.
Так глупо с моей стороны, это легко исправить с помощью следующих демонстраций
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
?Поскольку тогда существует только одна блокировка, оба метода блокируются, поэтому условие гонки решается напрямую.
Вид, который легко обмануть с помощью учебника;позор мне; (