• 17.死锁是如何产生的



    死锁是如何产生的

     引言

    本节介绍一个和同步所相关的知识点死锁。下面从3点来介绍死锁。

    第一点什么是死锁?第二点死锁是如何产生的?第三点编写一个死锁示例。

    什么是死锁?

    首先来看第一点,什么是死锁?死锁是指两个或两个以上的线程,在执行过程中,由于竞争资源或者是由于彼此通信而造成的一种阻塞现象,若无外力作用,他们都将无法推进下去。此时称系统处于死锁状态或系统产生的死锁,这些永远在互相等待的线程称为死锁线程。

    简而言之就是两个或两个以上的线程争夺彼此的锁造成阻塞,程序永远处于阻塞状态。

    这就好比一个女孩一个男孩,女孩手上有男孩想要的魔方,男孩手上有女孩想要的棒棒糖,然后女孩说我想要棒棒糖,接着男孩说我想要魔方,于是女孩对男孩说,你把棒棒糖给我,我就给你魔方。这时男孩也对女孩说,你把魔方给我,我就给你棒棒糖,于是他们谁都不让谁僵持住,这个过程就和死锁很像。

    下面我们把男孩女孩换成线程,看看线程a持有a锁,想要b锁,线程b持有b锁下想要a锁,

    他们互不相让,僵持住,形成了死锁局面。

    死锁是如何产生的?

    第一点介绍完了。我们再来看第二点,死锁是如何产生的? 


    死锁的产生主要有
    4个条件,

    第一个条件是两个或两个以上的线程,

    第二个条件是两个或两个以上的锁。

    第三个条件是两个或两个以上的线程持有不同所。

    第四个条件是持有不同锁的线程争夺对方的锁。

    编写一个死锁事例

    下面我们根据死锁的产生条件,来编写一个死锁事例,按照这4个条件一步一步编写。

    第一个条件

    首先是第一个条件,两个或两个以上的线程定义两个类,

    分别是locka和lockb然后继承thread类,于是线程a和线程b两个线程就准备好了。 

    第二个条件

    第一个条件应满足,再来看第二个条件,两个或两个以上的锁。分别在locka和lockb两个类里面边写一个静态同步方法,printera和printb.于是同步锁locka, lockb两个锁就准备好了。接着分别在两个方法里面输出a和b这个输出主要是用于观察方法是否被正常调用。在输出之前,我们使当前线程休眠一秒钟,此步骤为的是让线程不要太快执行完,待会还要在下面调用对方的方法去争夺对方的锁。

     第三个条件

    第二个条件以满足,再来看看第三个条件,两个或两个以上的线程持有不同的锁,很简单,直接重写run方法,然后在run方法里面分别调用printa和printb即可。

    于是线程a持有锁就是locka.class,因为是静态同步方法,所以锁的类型就是自身类名点class,同样的线程lockb就只有同步锁lockb.class,

    现在两个线程已经持有了不同的数。第三个条件已满足。

    第四个条件

    再来看看第四个条件,只有不同锁的线程去争夺对方的锁,我们只需在printA A方法里面去调用lockB .printB方法,在printAb方法里面去调用printA .printa方法即可,如此一来线程a就去争夺lockb的锁,线程b就去争夺locka的锁,最后1个条件也已经满足了,现在4个条件全部满足。 

    结果

    下面来启动这两个线程,首先将线程创建出来,然后启动他们。

    接下来我们去看看执行结果。从运行结果来看,两个线程分别在打印了a和b之后,进入相互争夺锁的过程,双方僵持住形成了死锁程序,想要停下来需手动关闭,也就是借助外力。

     总结

    最后来总结一下本节的内容。本节演示了死锁,死锁的定义在这里就不再赘述了。希望大家在以后使用同步的时候避免死锁。 

      

    附录:

    笔记完整文本:

    本节介绍一个和同步所相关的知识点死锁。下面从3点来介绍死锁。第一点什么是死锁?第二点死锁是如何产生的?第三点编写一个死锁示例。首先来看第一点,什么是死锁?死锁是指两个或两个以上的线程,在执行过程中,由于竞争资源或者是由于彼此通信而造成的一种阻塞现象,若无外力作用,他们都将无法推进下去。此时称系统处于死锁状态或系统产生的死锁,这些永远在互相等待的线程称为死锁县城。简而言之就是两个或两个以上的线程争夺彼此的所造成阻塞,程序永远处于阻塞状态。 这就好比一个女孩一个男孩,女孩手上有男孩想要的魔方,男孩手上有女孩想要的棒棒糖,然后女孩说我想要棒棒糖,接着男孩说我想要魔方,于是女孩对男孩说,你把棒棒糖给我,我就给你魔方。这时男孩也对女孩说,你把魔方给我,我就给你棒棒糖,于是他们谁都不让谁僵持住,这个过程就和死锁很像。下面我们把男孩女孩换成线程,看看线程a持有a锁,想要b锁,线程b持有b锁下压a锁,他们互不相让,僵持住,形成了死锁局面,第一点介绍完了。我们再来看第二点,死锁是如何产生的? 死锁的产生主要有4个条件,第一个条件是两个或两个以上的线程,第二个条件是两个或两个以上的锁。第三个条件是两个或两个以上的县城持有不同所。第四个条件是只有不同锁的线程争夺对方的锁。下面我们根据词所的产生条件,来编写一个搜索事例,按照这4个条件一步一步编写。首先是第一个条件,两个或两个以上的线程定义两个类,分别是洛克a和look b然后继承Siri的勒,于是线程a和线程b两个线程就准备好了。 第一个条件应满足,再来看第二个条件,两个或两个以上的锁分别在Outlook a和log b两个类里面边写一个静态同步方法,printer a和print的b于是同步锁look a look,b两个锁就准备好了。接着分别在两个方法里面输出a和b这个输出主要是用于观察方法是否被正常调用。在输出之前,我们使当前线程休眠一秒钟,此步骤为的是让县城不要太快执行完,待会还要在下面调用对方的方法去争夺对方的手。第二个条件以满足,再来看看第三个条件,两个或两个以上的线程持有不同勒索,很简单,直接重写run方法,然后在run方法里面分别调用prune的a普润的b即可。 于是线程a持有数就是录a、点class,因为是静态同步方法,所以所的类型就是自身类名点class,同样的线程look AP就只有同步锁log b点class,现在两个县城已经持有了不同的数。第三个条件已满足。再来看看第四个条件,只有不同锁的线程去争夺对方的锁,我们只需在point AA方法里面去调用oc bea点point bea方法,在普润的b方法里面去调用洛克a点普润的a方法即可,如此一来线程a就去争夺look b的锁,线程b就去争夺洛克a的锁,最后1个条件也已经满足了,现在4个条件全部满足。 下面来启动这两个线程,首先将线程创建出来,然后启动他们。接下来我们去看看执行结果。从运行结果来看,两个线程分别在打印了a和b之后,进入相互争夺锁的过程,双方僵持住形成了死锁程序,想要停下来需手动关闭,也就是借助外力。最后来总结一下本节的内容。本节演示了死锁,死锁的定义在这里就不再赘述了。希望大家在以后使用同步的时候避免死锁。

     

  • 相关阅读:
    SQL Server中行列转换 Pivot UnPivot
    div层拖动
    INamingContainer 接口
    nhibernet并发出错
    百度空间的密码帐号
    委托与事件入门经典
    Left Join、Right Join、Inner Join的区别
    C#操作剪贴板
    hibernate源码分析 持久化原理[摘自JavaEye]
    SQLSERVER条件语句IF应用
  • 原文地址:https://www.cnblogs.com/cj8357475/p/16086043.html
Copyright © 2020-2023  润新知