V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
RedBlackTree
V2EX  ›  程序员

可重入锁 RenentrantLock 是必不可少的吗?

  •  
  •   RedBlackTree · 2021-09-18 14:36:32 +08:00 · 2070 次点击
    这是一个创建于 1163 天前的主题,其中的信息可能已经有所发展或是发生改变。
    递归调用场景下,可以直接把锁提到最外面来避免死锁。
    我能想到的另一个重入锁的场景是,一个函数需要加锁但无法保证调用者是否已经占有锁,可能占有了锁,也可能没有占有锁,不可重入锁则函数需要提供两个变种,重入锁只需要提供一个就行了。
    Go 的 Sync.Mutex 是不可重入的,而且也没有提供可重入的锁。Java 中,可重入锁似乎是必须的,Java Concurrency in practive 书中讲可重入性时举了这么个例子:
    https://imgur.com/yDpZTfH
    在我看来,这是继承带来的耦合导致不得不使用重入锁来解决这个问题。
    我感觉可重入锁并不是必不可少的,请大家指点一下。
    7 条回复    2021-09-18 18:51:50 +08:00
    RedBlackTree
        1
    RedBlackTree  
    OP
       2021-09-18 14:43:27 +08:00
    怎么图片解析不出来?
    monetto
        2
    monetto  
       2021-09-18 14:52:49 +08:00   ❤️ 2
    RenentrantLock 只是没东西翻译了,翻译成了一个可重入锁,其实我觉得这玩意儿翻译成,“基于 AQS 的 公平 /非公平 且 可重入的锁”,像 synchronized 也是可重入的,只不过实现原理不一样。

    RenentrantLock 的原理是判断 AQS 的队列中,当前线程是否为链表头,那么就可以直接获取,不需要在 AQS 中排队。

    “递归调用场景下,可以直接把锁提到最外面来避免死锁”,这个形容不是很准确,有很多情况是,非递归调用,但是多线程情况下函数 A 和函数 B 的执行都需要这个独占资源,那么这时候就需要使用可重入锁。

    严格的说,为了解决的问题是 “某个线程,再次获取想要独占的资源”而出现的,这种情况在多线程编程很多时候是会出现的,这时候就需要可重入锁解决问题,不是耦合导致不得不重入。

    Go 是如何解决这种问题的我并不清楚,但是感觉原理应该和 JVM 差不多。
    chendy
        3
    chendy  
       2021-09-18 14:54:04 +08:00
    但是 java 里貌似也没有“不可重入”的锁
    A 和 B 俩方法用同一把锁,A 内部会调用 B,如果锁不可重入就直接卡死了
    BBCCBB
        4
    BBCCBB  
       2021-09-18 15:18:55 +08:00
    这个可以用 我可以不用, 但你不能没有 来解释.
    RedBlackTree
        5
    RedBlackTree  
    OP
       2021-09-18 15:30:25 +08:00
    @chendy 这种情况把方法内部逻辑拆出来,提供两个入口,一个默认未占有锁一个默认已占有锁也可以吧
    Brentwans
        6
    Brentwans  
       2021-09-18 17:10:32 +08:00
    重入锁的单位是线程,个人觉得这里的重入的特性,不算是必不可少的。
    Shaw314
        7
    Shaw314  
       2021-09-18 18:51:50 +08:00   ❤️ 1
    @chendy 线程池 ThreadPoolExecutor 里面的 Worker 类就通过 AQS 实现了一个不可重入的锁。 不过其实也不能算是锁,作用并不是用来控制并发的,主要是为了能标识这个 worker 是不是在工作,方便打断。https://github.com/daiqingliang/java_jdk1.8.0_111/blob/master/java/util/concurrent/ThreadPoolExecutor.java#L629
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1562 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 16:51 · PVG 00:51 · LAX 08:51 · JFK 11:51
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.