在学习操作系统时,已经反复理解很多遍了,所以我们直接给出死锁的例子:
一个经典的小品《不差钱》


赵本山:“你先上菜再唱”
小沈阳:“你不让我唱我就不给你上菜”
这不就是经典的死锁吗。
- public class DeadLock {
- public static void main(String[] args) {
- ServerDinner serverDinner = new ServerDinner(); //上菜的权利只有一份,这很重要!
- CanSing canSing = new CanSing(); //唱歌的权利只有一份,这很重要!
- //赵本山:拥有让小沈阳唱歌的权利,还想要上菜
- ZhaoBenShan zhaoBenShan = new ZhaoBenShan(serverDinner,canSing);
- zhaoBenShan.start();
- //小沈阳:拿着上菜的权利,还想要唱歌的权利
- XiaoShenYang xiaoShenYang = new XiaoShenYang(serverDinner,canSing);
- xiaoShenYang.start();
- }
- }
-
- //上菜的权利
- class ServerDinner{ }
-
- //唱歌的权利
- class CanSing{}
-
- //小沈阳:拿着上菜的权利,还想要唱歌的权利
- class XiaoShenYang extends Thread{
- ServerDinner serverDinner;
- CanSing canSing;
-
- public XiaoShenYang(ServerDinner serverDinner,CanSing canSing){
- this.serverDinner = serverDinner;
- this.canSing = canSing;
- }
-
- @Override
- public void run() {
- synchronized (serverDinner){
- System.out.println("小沈阳:你不让我唱歌我就不给你上菜");
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
-
- synchronized (canSing){
- System.out.println("小沈阳:成功唱歌");
- }
- }
- }
- }
-
- //赵本山:拥有让小沈阳唱歌的权利,还想要上菜
- class ZhaoBenShan extends Thread{
- ServerDinner serverDinner;
- CanSing canSing;
-
- public ZhaoBenShan(ServerDinner serverDinner,CanSing canSing){
- this.serverDinner = serverDinner;
- this.canSing = canSing;
- }
-
- @Override
- public void run() {
- synchronized (canSing){
- System.out.println("赵本山:先上菜再唱歌");
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
-
- synchronized (serverDinner){
- System.out.println("赵本山:成功得到菜");
- }
- }
- }
- }
运行结果:

注意,唱歌的权利和上菜的权利只能有一份。如果唱歌或者上菜的权利有两份,那么就不会产生死锁了。

如何避免(不知道这里“避免”用的对不对哈)死锁?
对于小沈阳,把 synchronized (canSing) 的代码段拿出来从 synchronized (serverDinner)中拿出来 。也就意味着让出上菜的权利之后,再去索要唱歌的权利。

对于赵本山,同样的道理。先让出唱歌的权利,再索要上菜的权利。

在模拟Rip协议的项目中,自己处理完几个死锁问题,就彻底明白了如何分析,解决死锁。所以,光学习只有输入不行,必须有项目实战作为输出!