银行家算法

来源:互联网 发布:从事数据分析看什么书 编辑:程序博客网 时间:2024/06/05 00:14

死锁描述


死锁是操作系统层面的一个错误,是进程死锁的简称,最早在 1965 年由 Dijkstra 在研究银行家算法时提出的,它是计算机操作系统乃至整个并发程序设计领域最难处理的问题之一。

事实上,计算机世界有很多事情需要多线程方式去解决,因为这样才能最大程度上利用资源,才能体现出计算的高效。但是,实际上来说,计算机系统中有很多一次只能由一个进程使用的资源的情况,例如打印机,同时只能有一个进程控制它。在多通道程序设计环境中,若干进程往往要共享这类资源,而且一个进程所需要的资源还很有可能不止一个。因此,就会出现若干进程竞争有限资源,又推进顺序不当,从而构成无限期循环等待的局面。我们称这种状态为死锁。简单一点描述,死锁是指多个进程循环等待它方占有的资源而无限期地僵持下去的局面。很显然,如果没有外力的作用,那么死锁涉及到的各个进程都将永远处于封锁状态。

系统发生死锁现象不仅浪费大量的系统资源,甚至导致整个系统崩溃,带来灾难性后果。所以,对于死锁问题在理论上和技术上都必须予以高度重视。


银行家算法


一个银行家如何将一定数目的资金安全地借给若干个客户,使这些客户既能借到钱完成要干的事,同时银行家又能收回全部资金而不至于破产。银行家就像一个操作系统,客户就像运行的进程,银行家的资金就是系统的资源。

银行家算法需要确保以下四点:

1、当一个顾客对资金的最大需求量不超过银行家现有的资金时就可接纳该顾客;

2、顾客可以分期贷款, 但贷款的总数不能超过最大需求量;

3、当银行家现有的资金不能满足顾客尚需的贷款数额时,对顾客的贷款可推迟支付,但总能使顾客在有限的时间里得到贷款;

4、当顾客得到所需的全部资金后,一定能在有限的时间里归还所有的资金。


死锁示例

死锁问题是多线程特有的问题,它可以被认为是线程间切换消耗系统性能的一种极端情况。在死锁时,线程间相互等待资源,而又不释放自身的资源,导致无穷无尽的等待,其结果是系统任务永远无法执行完成。死锁问题是在多线程开发中应该坚决避免和杜绝的问题。

一般来说,要出现死锁问题需要满足以下条件:

1、互斥条件:一个资源每次只能被一个线程使用。

2、请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。

3、不剥夺条件:进程已获得的资源,在未使用完之前,不能强行剥夺。

4、循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。


public class ThreadDeadlock {    public static void main(String[] args) throws InterruptedException {    Object obj1 = new Object();    Object obj2 = new Object();    Object obj3 = new Object();    Thread t1 = new Thread(new SyncThread(obj1, obj2), "t1");    Thread t2 = new Thread(new SyncThread(obj2, obj3), "t2");    Thread t3 = new Thread(new SyncThread(obj3, obj1), "t3");    t1.start();    Thread.sleep(5000);    t2.start();    Thread.sleep(5000);    t3.start();    }   }   class SyncThread implements Runnable{    private Object obj1;    private Object obj2;    public SyncThread(Object o1, Object o2){    this.obj1=o1;    this.obj2=o2;    }    @Override    public void run() {    String name = Thread.currentThread().getName();    System.out.println(name + " acquiring lock on "+obj1);    synchronized (obj1) {    System.out.println(name + " acquired lock on "+obj1);    work();    System.out.println(name + " acquiring lock on "+obj2);    synchronized (obj2) {    System.out.println(name + " acquired lock on "+obj2);    work();    }    System.out.println(name + " released lock on "+obj2);    }    System.out.println(name + " released lock on "+obj1);    System.out.println(name + " finished execution.");    }    private void work() {    try {    Thread.sleep(30000);    } catch (InterruptedException e) {    e.printStackTrace();    }    }   }





0 0
原创粉丝点击