1
RedBlackTree OP 怎么图片解析不出来?
|
2
monetto 2021-09-18 14:52:49 +08:00 2
RenentrantLock 只是没东西翻译了,翻译成了一个可重入锁,其实我觉得这玩意儿翻译成,“基于 AQS 的 公平 /非公平 且 可重入的锁”,像 synchronized 也是可重入的,只不过实现原理不一样。
RenentrantLock 的原理是判断 AQS 的队列中,当前线程是否为链表头,那么就可以直接获取,不需要在 AQS 中排队。 “递归调用场景下,可以直接把锁提到最外面来避免死锁”,这个形容不是很准确,有很多情况是,非递归调用,但是多线程情况下函数 A 和函数 B 的执行都需要这个独占资源,那么这时候就需要使用可重入锁。 严格的说,为了解决的问题是 “某个线程,再次获取想要独占的资源”而出现的,这种情况在多线程编程很多时候是会出现的,这时候就需要可重入锁解决问题,不是耦合导致不得不重入。 Go 是如何解决这种问题的我并不清楚,但是感觉原理应该和 JVM 差不多。 |
3
chendy 2021-09-18 14:54:04 +08:00
但是 java 里貌似也没有“不可重入”的锁
A 和 B 俩方法用同一把锁,A 内部会调用 B,如果锁不可重入就直接卡死了 |
4
BBCCBB 2021-09-18 15:18:55 +08:00
这个可以用 我可以不用, 但你不能没有 来解释.
|
5
RedBlackTree OP @chendy 这种情况把方法内部逻辑拆出来,提供两个入口,一个默认未占有锁一个默认已占有锁也可以吧
|
6
Brentwans 2021-09-18 17:10:32 +08:00
重入锁的单位是线程,个人觉得这里的重入的特性,不算是必不可少的。
|
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
|