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

死锁的四个必要条件:

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

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

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;i<n;i++){
        //输入每个进程的request
        //先分配资源,然后进行安全检查,如果安全,则继续分配,如果不安全,则资源恢复,进程等待
        for(int j=0;j<m;j++){
            request[j]=sc.nextInt();
            if(request[j]>Max[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<m;w++)work[w]=available[w];
        int count=0;
        for(int u=0;u<n;u++){
            for(int v=0;v<m;v++){
                if(finish[u]==false && need[u][j]<=work[u][j]){count++;}
            }
            if(count==m){
                for(int s=0;s<n;s++){
                    work[s]+=allocation[u][s];//假设所有分配出去的资源都能限时回收
                }
               finish[u]=true;
           }
        }
        for(int c=0;c<n;c++){
            if(!finish[c]){
                 //说明不能形成安全序列,之前的资源分配不合理,把分配出的资源回收
                 available[i][j]+=request[j];
                 allocation[i][j]-=request[j];
                 need[i][j]+=request[j];
                 break outer;
             }
        }
       //说明之前的分配资源合理的
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值