快速理解入门死锁概念(配Java实例)

2 篇文章 0 订阅
1 篇文章 0 订阅

1.什么是死锁?

        先看看比较官方的解释:死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去;此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。

        通俗来说,就是多个进程之间互相持有对方想要的资源,但又都不放手,从而形成的一种僵持的状态。

跳出计算机概念,生活里其实不乏类似于这样死锁的概念。比如有两个互相竞争的死对头无意中得到了一个神人的馈赠,神人想要给这两人一个宝箱,但神人知道这两人是死对头,倘若把宝箱给出去,必定会抢得一死一伤的,因此神人是这样给的:给其中一个人一把开宝箱的钥匙,而另一个人怀揣着宝箱。这样,除非他们要么愿意让出自己占有的主动让给对方,要么抢夺对方,不然他们都不能得到宝箱里面的东西。如果他们都是倔牛,不让不抢,就是耗着(诶,就是玩儿)。这时,我们可以说,这种状态被僵持住了,即死锁。

2.死锁产生的条件?

上面的例子如果能理解,那么死锁条件也就能先懂一二了。

(1)互斥条件。

进程对所分配到的资源进行排他性使用,即在一段时间,某资源只能被一个进程占用。

就像一把钥匙只能被一个人拿着,一个宝箱也只能被一个人拿着。

(2)请求和保持条件

进程已经保持了至少一个资源,但又提出了新的资源请求,而该资源已被其他进程占有,此时请求进程被阻塞,但对自己获得的资源保持不变。”

都在求着对方给出钥匙或宝箱,但各自又想着“我想你给我,我反正不会先给”。

(3)不可抢占条件

进程已获得的资源在未使用完之前不能被抢占,只能在进程使用完时由自己释放。

就像这两人虽然是死对头,但又是武林中人,年轻人讲武德,都不主动抢对方的,但又坚守自己的东西。

(4)循环等待条件

简单来说,就是互相耗着呗。

3.用Java代码展现死锁过程

package com.example.zhan;

import java.io.ObjectInputStream;

public class Threadsafe02 {

    public static void main(String[] args) {

        Object o = new Object();
        Object o1 = new Object();

        MyThread3 myThread3 = new MyThread3(o, o1);
        MyThread4 myThread4 = new MyThread4(o, o1);


        myThread3.start();
        myThread4.start();


    }


}


class MyThread3 extends Thread{

    Object o1;
    Object o2;

 public MyThread3(Object o1,Object o2){

         this.o1=o1;
         this.o2=o2;

 }
    @Override
    public void run() {

       synchronized (o1){
           try {
               Thread.sleep(1000);
           } catch (InterruptedException e) {
               e.printStackTrace();
           }
           synchronized (o2){
           }
       }
 }


    }


class MyThread4 extends Thread{
    Object o1;
    Object o2;

    public MyThread4(Object o1,Object o2){
        this.o1=o1;
        this.o2=o2;
    }

    @Override
    public void run() {
        synchronized (o2){
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            synchronized (o1){

            }
        }

    }
}

上面,我用了synchronized关键字,之后也会详细介绍其用法,简单说这是一个锁,可以锁对象或方法或变量等。作用当进程访问对象时,可以保证对象的某些资源或对象本身不被其他进程访问。

我用了MyThread3和MyThread4两个线程去获取o1,o2两个资源。可以看到每个线程方法中我都用了两个synchronized嵌套对象o1,o2,表示只有某个进程要同时获取了o1,o2,synchronized才会被揭开。当然,为了防止运行那一刻,某一进程直接就把o1,o2拿走了,我就用了sleep去延缓。

结果:

可以看到,一直在运行,并且无结束状态。当然,也不可能结束了,这种僵持的时间,可真就堪称互相等到天荒地老的真爱了(doge)。

 

  • 5
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蜗牛变涡流

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值