什么是死锁,怎样有效的避免死锁,银行家算法

死锁的四个必要条件:

互斥条件:一个资源只能被一个线程占用
请求与保持条件:一个线程因请求资源被阻塞时,对获得的资源保持不放
不剥夺条件:线程已经获得的资源,没有使用完,不能强行剥夺
循环等待条件:若干进程形成的首尾相连的等待状态

避免死锁就是要让这四个必要条件不成立:

1.避免线程在阻塞状态的时候继续占用资源,或者让线程请求下一个资源的时候释放当前资源
2.资源可以按照优先级有序分配,避免线程永久占据资源
3.允许高优先级的线程抢占资源,但是在优先级相同时是无效的
4.破坏循环等待条件,对资源的请求只允许升序。
5.实际应用中不能完全的避免死锁,因此有检测死锁和解除死锁的方法,使用的就是银行家算法的安全性检测
如果某个资源的分配导致后面的线程不能成功finish,则回收之前尝试分配的资源。

可以用一个map来实现死锁的检测:

线程A:获得1锁,申请2锁
线程B:获得2锁,申请3锁
线程C:获得3锁,申请1锁
当后面的线程请求前面的线程已经获得的锁的时候,可以检测到一条锁的闭环,出现死锁

银行家算法是怎么实现的
进程向系统申请的资源数,小于当前可用资源+其他线程占用资源的总和。所有进程能建立一个安全序列的时候,认为可以将资源分配给当前进程,否则该进程要等待。

int m,n;//m类资源,n个线程
int[] avaliable=new int[m];        //表示每类资源的可用数量
int[][] allocation=new int[n][m];  //表示已分配给每个进程的资源数量
int[][] Max=new int[n][m];         //表示每个进程最大需求
int[][] need=new int[n][m];        //表示每个进程仍需获得的资源数
Scanner sc=new Scanner(System.in);
int[] request=new int[m];
outer:
    for(int i=0;iMax[i][j])break outer; //说明出错
            //尝试分配资源
            available[i][j]-=request[j];
            allocation[i][j]+=request[j];
            need[i][j]-=request[j];
        }
        //进行安全性检查
        //获取finish和work初值
        boolean[] finish=new boolean[n];//n个进程是否都能成功finish
        int[] work=new int[m];
        for(int w=0;w

你可能感兴趣的:(JAVA,java,死锁)