25

Lock 和 Condition 并发编程大师重复造轮子?

 4 years ago
source link: https://mp.weixin.qq.com/s/-t0jJUIrssY8Bjxz6mMWFw
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

3QVbeu7.jpg!web

Photo By Instagram sooyaaa

昨天的问题

Java 在语法层面已经有了 synchronized 来实现管程,为什么还要在 JDK 中提供了 Lock 和 Condition 工具类来做这样的事情,这属于重复造轮子吗?

我的答案

首先你可能会想到的是 synchronized 性能问题,但是我想告诉你的是 synchronized 在高版本的 JDK 中性能已经得到了大幅的提升,很多开发者开始提倡使用 synchronized,性能问题可以不断优化提升,它并不是重载轮子的原因。

大家都知道管程帮助我们解决了多线程资源共享问题,但同时也带来了死锁的风险。Coffman 等人在 1971 年总结出来产生死锁的四个必要条件:

1. 互斥条件

一个资源在同一时刻只能被一个线程操作。

2. 占有且等待

线程因为请求资源而阻塞时不会释放已经获取到的资源。

3. 不可强行占有

线程已经获取到的资源,在未释放前不允许被其他线程强行剥夺。

4. 循环等待

线程存在循环等待资源的关系(线程 T1 依次占有资源 A,B;线程 T2 依次占有资源 B,A;这就构成了循环等待资源关系)。

当发生死锁的时候必然上面四个条件都会满足,那么只要我们破坏其中的任何一个条件,我们即可解决死锁问题。首先条件 1 无法破解,因为共享资源必须是互斥的,如果可以多个线程同时操作也没必要加锁了。那我们试图使用 synchronized 来破解剩余的三个条件:

1. 占有且等待

synchronized 获取资源时候,只要资源获取不到,线程立即进入阻塞状态,并且不会释放已经获取的资源。那么我们可以调整一下获取共享资源的方式,我们通过一个锁中介,通过中介一次性获取线程需要的所有资源,如果存在单个资源不满足情况,直接阻塞,而不是获取部分资源,这样我们即可解决这个问题,破解该条件。

2. 不可强行占有

synchronized 获取不到资源时候,线程直接阻塞,无法被中断释放资源,因此这个条件 synchronized 无法破解。

3. 循环等待

循环等待是因为线程在竞争 2 个互斥资源时候会以不同的顺序去获取资源,如果我们将线程获取资源的顺序固定下来即可破解这个条件。

综上我们可以知道 synchronized 不能破解“不可强行占有”条件,这就是 JDK 同时提供 Lock 这种管程的实现方式的原因。当然啦,Lock 使用起来也更加的灵活。例如我们有多个共享资源,锁是嵌套方式获取的,如线程需要先获取 A 锁,然后获取 B 锁,然后释放 A 锁,获取 C 锁,接着释放 B 锁,获取 D 锁 等等。这种嵌套获取锁的方式 synchronized 是无法实现的,但是 Lock 却可以帮助我们来解决这个问题。既然我们知道了 JDK 重造管程的原因,那我们来一起看一下 Lock 为我们提供的四种进入获取锁的方式:

1. void lock();

这种方式获取不到锁时候线程会进入阻塞状态,和 synchronized 类似。

2. void lockInterruptibly() throws InterruptedException;

这种方式获取不到锁线程同样会进入阻塞,但是它可以接收中断信号,退出阻塞。

3. boolean tryLock();

这种方式不管是否能获取到锁都不会阻塞而是立刻返回获取结果,成功返回 true,失败返回 false。

4. boolean tryLock(long time, TimeUnit unit) throws InterruptedException;

这种方式获取不到锁的线程会进入阻塞状态,但是在指定的时间内如果仍未获得锁,则返回 false,否则返回 true。

以上即为昨天的问题的答案,小伙伴们对这个答案是否满意呢?欢迎留言和我讨论。

又要到年末了,你是不是又悄咪咪的开始看机会啦。 为了广大小伙伴能充足电量,能顺利通过 BAT 的面试官无情三连炮,我特意推出大型刷题节目。 每天一道题目,第二天给答案,前一天给小伙伴们独立思考的机会。

mymmQfz.jpg!web

点下“在看”,鼓励一下?


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK