为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

摇曳的蔷薇 2022-09-14 10:16:48
我正在尝试遵循Java中的重入锁示例,同步与重入锁之间的区别类型的教程。我有一个演示开始于-eapublic 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,我删除了类中定义的,并使用本地锁,如下所示,但它仍然不起作用。CountLockprivate 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();    }}这里遗漏的要点是什么?任何帮助将不胜感激;)
查看完整描述

1 回答

?
Cats萌萌

TA贡献1805条经验 获得超9个赞

有点傻自己。


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


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


查看完整回答
反对 回复 2022-09-14
  • 1 回答
  • 0 关注
  • 110 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号