java死锁解析

news/2024/5/20 15:56:39 标签: java, 死锁

2个经典的例子

1.银行家算法(在其他博客上摘抄修改)

 

  这是一个著名的避免死锁的算法,是由Dijstra首先提出来并加以解决的。 

 

  [背景知识]

 

  一个银行家如何将一定数目的资金安全地借给若干个客户,使这些客户既能借到 

钱完成要干的事,同时银行家又能收回全部资金而不至于破产,这就是银行家问题 

。这个问题同操作系统中资源分配问题十分相似:银行家就像一个操作系统,客户 

就像运行的进程,银行家的资金就是系统的资源。

 

  [问题的描述]

 

  一个银行家拥有一定数量的资金,有若干个客户要贷款。每个客户须在一开始就 

声明他所需贷款的总额。若该客户贷款总额不超过银行家的资金总数,银行家可以 

接收客户的要求。客户贷款是以每次一个资金单位(如1RMB等)的方式进行的, 

客户在借满所需的全部单位款额之前可能会等待,但银行家须保证这种等待是有限 

的,可完成的。

 

  例如:有三个客户C1C2C3,向银行家借款,该银行家的资金总额为10个资金 

单位,其中C1客户要借9各资金单位,C2客户要借3个资金单位,C3客户要借8个资金 

单位,总计20个资金单位。某一时刻的状态如图所示。

 

  

 

 

 

 

 

 

 

 

 

                                       银行家算法示意

 

  对于a图的状态,按照安全序列的要求,我们选的第一个客户应满足该客户所需的 

贷款小于等于银行家当前所剩余的钱款,可以看出只有C2客户能被满足:C2客户需1 

个资金单位,小银行家手中的2个资金单位,于是银行家把1个资金单位借给C2客户 

,使之完成工作并归还所借的3个资金单位的钱,进入b图。同理,银行家把4个资金 

单位借给C3客户,使其完成工作,在c图中,只剩一个客户C1,它需7个资金单位, 

这时银行家有8个资金单位,所以C1也能顺利借到钱并完成工作。最后(见图d)银 

行家收回全部10个资金单位,保证不赔本。那麽客户序列{C1C2C3}就是个安全 

序列,按照这个序列贷款,银行家才是安全的。否则的话,若在图b状态时,银行家 

把手中的4个资金单位借给了C1,则出现不安全状态:这时C1C3均不能完成工作, 

而银行家手中又没有钱了,系统陷入僵持局面,银行家也不能收回投资。

 

  综上所述,银行家算法是从当前状态出发,逐个按安全序列检查各客户谁能完成 

其工作,然后假定其完成工作且归还全部贷款,再进而检查下一个能完成工作的客 

户,......。如果所有客户都能完成工作,则找到一个安全序列,银行家才是安全 

的。

 

  从上面分析看出,银行家算法允许死锁必要条件中的互斥条件,占有且申请条件 

,不可抢占条件的存在,这样,它与预防死锁的几种方法相比较,限制条件少了, 

资源利用程度提高了。

 

这是该算法的优点。其缺点是:

 

   1〉这个算法要求客户数保持固定不变,这在多道程序系统中是难以做到的。   

 

 

   2〉这个算法保证所有客户在有限的时间内得到满足,但实时客户要求快速响 

应,所以要考虑这个因素。  

 

    3〉由于要寻找一个安全序列,实际上增加了系统的开销。

2.经典问题-哲学家就餐(有关死锁的情况)


http://www.niftyadmin.cn/n/773952.html

相关文章

java线程的六大状态

在java的API中线程的六个状态: 1.新建状态(new):使用new创建一个线程对象,仅仅在堆内存中分配一个内存空间(和普通的创建对象一样),在调用start方法之前,在此状态下&…

java线程的六个状态

在java的API中线程的六个状态: 1.新建状态(new):使用new创建一个线程对象,仅仅在堆内存中分配一个内存空间(和普通的创建对象一样),在调用start方法之前,在此状态下&…

java的sleep(),join()和后台线程详解

线程睡眠Sleep()方法 在Thread类中有两个sleep()方法,但是计算机硬件很难精确到纳秒,所以我们输入的数字一般以毫秒为单位。 调用方法之后,当前线程会放弃cpu,至指定的时间段内&am…

java线程优先级

每一个线程都有优先级,但是并不是优先级高的线程会先执行,优先级高的执行的次数会比较多,具体的执行顺序还是根据JVM的调度。 在Thread类中有三个字段来表示线程的优先级 MAX_PRIORITY : (10)最高优先级 …

java线程礼让

yield()方法:表示当前线程对象提示调度器自己愿意让出CPU资源,但是调度器可以自由忽略。 调用该方法后,线程对象处于就绪状态,所以完全有可能:某个线程调用yield()方法后…

java定时器和线程组

可以定时执行指定的任务,可以用于做电子时钟,闹钟,窗口的晃动(根据特定的时间段改变窗口对于桌面的位置) TimerTask Timer 这个类是线程安全的:多个线程可以共享一个单一的Timer对象而不需要外部同步。 电…

ArrayList(数组列表)

在数据结构中,讲解ArrayList类,首先数据结构是用来CRUD的。在此类中有充分的实现 和Vector不同,ArrayList中的操作不是线程安全的!所以,建议在单线程中才使用ArrayList,而在多线程中可以选择Vector或者Cop…

LinkedList(链表列表)

LinkedList主要有两种形式:单向链表和双向链表(一般会用 双向链表) 根据API1.6中可以知道: 1.和Arra&#x…