预防和避免死锁的方法及银行家算法的java简单实现
- 预防死锁
(1) 摒弃“请求和保持”条件
基本思想:规定所有进程在开始运行之前,要么获得所需的所有资源,要么一个都不分配给它,直到所需资源全部满足才一次性分配给它。
优点:简单、易于实现且很安全
缺点:资源被严重浪费,进程延迟运行
(2) 摒弃“不剥夺”条件
基本思想:当一个已经保持了某些资源的进程,再提出新的资源请求而不能立即得到满足时,必须释放它已经保持了的所有资源,待以后需要时再重新申请。这意味着某一进程已经占有的资源,在运行过程中会被暂时地释放掉,也可认为是被剥夺了,从而摒弃了“不剥夺”条件。
(3) 摒弃“环路等待”条件
基本思想:系统将所有资源按类型进行线性排队,并赋予不同的序号,所有进程对资源的请求必须严格按照资源序号递增的次序提出。由于只允许在保持高顺位资源的情况下申请低顺位资源,不允许在保持低顺位资源的情况下申请高顺位资源,因此环路等待条件被破坏。 - 避免死锁
(1) 系统的安全状态
所谓安全状态,是指系统能按某种进程顺序(P1,P2,…,Pn),来为每个进程Pi分配其所需资源,直至满足每个进程对资源的最大需求,使每个进程都可顺利地完成,称系统处于安全状态, 称〈P1,P2,…,Pn〉序列为安全序列 。如果系统无法找到这样一个安全序列,则称系统处于不安全状态。
安全状态,一定不会死锁;
不安全状态不必然死锁;
避免死锁的实质在于:系统在进行资源分配时,如何避免系统不进入不安全状态。
(2) 利用银行家算法避免死锁
一、进程向操作系统请求分配资源相当于用户银行贷款,为保证资金安全:
①当一个顾客对资金的最大需求量不超过银行家现有的资金就可以接纳该顾客;
②顾客可以分期贷款,但总数不能超过最大需求
③银行家现有资金不满足顾客,可以推迟,但顾客会在有限时间内获得贷款
④顾客得到全部资金后会在有限时间内归还。
二、从操作系统角度来看:
进程首次申请资源,系统现存资源>线程最大资源需求时分配,否则延迟;
进程执行期间,进程本次申请的资源数<系统剩余资源数,分配,否则延迟.
三、举个栗子
假定系统中有五个进程{P0,P1,P2,P3,P4}和三类资源{A,B,C},各种资源的数量分别为10、5、7,在T0时刻的资源分配情况如下:

存在安全序列:
(P1,P3,P4,P0,P2) OR (p1 p3 p0 p2 p4) - 银行家算法的java简单实现
①首先创建一个用户类
/*
* 用户类
*/
public class Person {
//用户名字
private String name;
//用户所需最大资源数
private int[] max;
//用户现有资源数
private int[] allocation;
//用户所需资源数
private int[] need;
//用户请求资源数,本实例中请求数require等于need所需资源数
private int[] require;
public Person(String name) {
this.name = name;
}
@Override
public String toString() {
// TODO Auto-generated method stub
return name;
}
public void setMax(int[] max) {
this.max = max;
System.out.println(name + "最大资源需求");
for(int i = 0; i < max.length; i++) {
System.out.print(i + ":" + max[i] + " ");
}
System.out.println();
}
public int[] getMax() {
return max;
}
public int[] getAllocation() {
return allocation;
}
public void setAllocation(int[] allocation) {
this.allocation = allocation;
System.out.println(name + "当前拥有资源");
for(int i = 0; i < allocation.length; i++) {
System.out.print(i + ":" + allocation[i] + " ");
}
System.out.println();
}
public int[] getNeed() {
return need;
}
public void setNeed() {
int[] need1 = new int[max.length];
for(int i = 0; i < max.length; i++) {
need1[i] = max[i] - allocation[i];
}
this.need = need1;
System.out.println(name + "所需资源");
for(int i = 0; i < need.length; i++) {
System.out.print(i + ":" + need[i] + " ");
}
System.out.println();
}
public int[] getRequire() {
return require;
}
public int[] setRequire() {
this.require = need;
System.out.println(name + "发起请求");
for(int i = 0; i < require.length; i++) {
System.out.print(i + ":" + require[i] + " ");
}
System.out.println("");
System.out.println("----------");
return require;
}
}
②创建银行家类并进行测试
public class BlankTest {
//list1中存储竞争资源的用户
public static ArrayList<Person> list1 = new ArrayList<>();
//list2已经完成的用户
public static ArrayList<Person> list2 = new ArrayList<>();
//银行家现有资源
public static int[] avaiable = new int[3];
/*
* 是否可以分配,即请求是否小于系统现有资源
*/
public static boolean CanRequired(int[] avaiable, int [] require) {
for(int i = 0; i < avaiable.length; i++) {
if(avaiable[i] < require[i]) {
return false;
}
}
return true;
}
/*
* 分配动作
*/
public static void send(int[] avaiable, int [] allocation) {
System.out.println("系统现有资源");
for(int j = 0; j < avaiable.length; j++) {
avaiable[j] = avaiable[j] + allocation[j];
System.out.print(avaiable[j] + " ");
}
System.out.println();
}
/*
* 初始化数据和测试
*/
public static void main(String[] args) {
//初始化资源
avaiable[0] = 3;
avaiable[1] = 3;
avaiable[2] = 2;
int[] max1 = new int[3];
max1[0] = 7;
max1[1] = 5;
max1[2] = 3;
int[] allocation1 = new int[3];
allocation1[0] = 0;
allocation1[1] = 1;
allocation1[2] = 0;
Person p0 = new Person("p0");
p0.setMax(max1);
p0.setAllocation(allocation1);
p0.setNeed();
int[] max2 = new int[3];
max2[0] = 3;
max2[1] = 2;
max2[2] = 2;
int[] allocation2 = new int[3];
allocation2[0] = 2;
allocation2[1] = 0;
allocation2[2] = 0;
Person p1 = new Person("p1");
p1.setMax(max2);
p1.setAllocation(allocation2);
p1.setNeed();
int[] max3 = new int[3];
max3[0] = 9;
max3[1] = 0;
max3[2] = 2;
int[] allocation3 = new int[3];
allocation3[0] = 3;
allocation3[1] = 0;
allocation3[2] = 2;
Person p2 = new Person("p2");
p2.setMax(max3);
p2.setAllocation(allocation3);
p2.setNeed();
int[] max4 = new int[3];
max4[0] = 2;
max4[1] = 2;
max4[2] = 2;
int[] allocation4 = new int[3];
allocation4[0] = 2;
allocation4[1] = 1;
allocation4[2] = 1;
Person p3 = new Person("p3");
p3.setMax(max4);
p3.setAllocation(allocation4);
p3.setNeed();
int[] max5 = new int[3];
max5[0] = 4;
max5[1] = 3;
max5[2] = 3;
int[] allocation5 = new int[3];
allocation5[0] = 0;
allocation5[1] = 0;
allocation5[2] = 2;
Person p4 = new Person("p4");
p4.setMax(max5);
p4.setAllocation(allocation5);
p4.setNeed();
System.out.println();
list1.add(p0);
list1.add(p1);
list1.add(p2);
list1.add(p3);
list1.add(p4);
//index用于记录每趟循环是否有用户得到资源,没有说明不存在安全序列,结束分配
int index = 0;
//开始分配
for(int x = 0; x < list1.size(); x++) {
if(index != x) {
System.out.println("找不到安全队列");
break;
}
for(int z = 0; z < list1.size(); z++) {
/*
* 判断请求资源是否小于系统现有资源,并且该用户需要满足不在安全序列中,这里的请求是简单的一次请求
*/
if(CanRequired(avaiable, list1.get(z).setRequire()) && !list2.contains(list1.get(z))) {
System.out.println("该请求得到响应");
index++;
send(avaiable, list1.get(z).getAllocation());
list2.add(list1.get(z));
break;
}
}
}
System.out.println();
for(Person p: list2) {
System.out.print(p + " ");
}
}
}
③测试结果
初始化资源

分配

最终结果

预防和避免死锁的方法及银行家算法的java简单实现的更多相关文章
- [OS] 死锁相关知识点以及银行家算法详解
因此我们先来介绍一下死锁: 死锁特征 当出现死锁时,进程永远不能完成,并且系统资源被阻碍使用,阻止了其他作业开始执行.在讨论处理死锁问题的各种方法之前,先深入讨论一下死锁的特征. ·必要条件 (1)互 ...
- java面试题之死锁产生的条件,以及如何避免死锁,银行家算法,产生死锁后如何解决(阿里面试题)
死锁产生的四个必要条件: 互斥:一个资源每次只能被一个进程使用(资源独立) 请求与保持:一个进程因请求资源而阻塞时,对已获得的资源保持不放(不释放锁) 不剥夺:进程已获得的资源,在未使用之前,不能强行 ...
- c/c++多线程模拟系统资源分配(并通过银行家算法避免死锁产生)
银行家算法数据结构 (1)可利用资源向量Available 是个含有m个元素的数组,其中的每一个元素代表一类可利用的资源数目.如果Available[j]=K,则表示系统中现有Rj类资源K个. (2) ...
- 避免死锁的银行家算法C++程序实现
本篇博文为追忆以前写过的算法系列第二篇(20081021) 温故知新 目的:具有代表性的死锁避免算法是Dijskstra给出的银行家算法.本实验是基于银行家算法的思想通过编写C++程序实现银行家 ...
- SQLServer查看和解决死锁的方法
http://luohonghong.blog.163.com/blog/static/78312058201142411533316/ SQLServer查看和解决死锁的方法 2011-05-24 ...
- sqlserver2008 死锁解决方法及性能优化方法
sqlserver2008 死锁解决方法及性能优化方法 原文: http://blog.csdn.net/kuui_chiu/article/details/48621939 十步优化SQL Serv ...
- 多任务-python实现-死锁,银行家算法(2.1.5)
@ 目录 1.死锁 2.避免死锁的方式-银行家算法 1.死锁 死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去.此时称系 ...
- 一文了解MySQL性能测试及调优中的死锁处理方法,你还看不明白?
一文了解MySQL性能测试及调优中的死锁处理方法,你还看不明白? 以下从死锁检测.死锁避免.死锁解决3个方面来探讨如何对MySQL死锁问题进行性能调优. 死锁检测 通过SQL语句查询锁表相关信息: ( ...
- C程序模拟实现银行家算法
C程序模拟实现银行家算法 上周又做操作系统实验,题目是用程序模拟实现银行家算法,写了半天还真有点晕,主要是因为想尽可能符合课本上的描述,所以写出来的程序就比较恶心了,好了,银行家算法就不多说了,不了解 ...
随机推荐
- 使用delphi-cross-socket 开发kbmmw smart http service
前几天我说了使用delphi-cross-socket 扩展kbmmw 的跨平台支持,今天我说一下使用 kbmMWCrossScoketHttpServerTransport 在linux 下支持 k ...
- kbmmw 5.01 发布
Important notes (changes that may break existing code) ============================================= ...
- 一道另类的区间dp题 -- P3147 [USACO16OPEN]262144
https://www.luogu.org/problemnew/show/P3147 此题与上一题完全一样,唯一不一样的就是数据范围; 上一题是248,而这一题是262144; 普通的区间dp表示状 ...
- 2019.01.14 bzoj5343: [Ctsc2018]混合果汁(整体二分+权值线段树)
传送门 整体二分好题. 题意简述:nnn种果汁,每种有三个属性:美味度,单位体积价格,购买体积上限. 现在有mmm个询问,每次问能否混合出总体积大于某个值,总价格小于某个值的果汁,如果能,求所有方案中 ...
- 2018.11.24 poj3261Milk Patterns(后缀数组)
传送门 后缀数组经典题. 貌似可以用二分答案+后缀数组? 我自己yyyyyy了一个好写一点的方法. 直接先预处理出heightheightheight数组. 然后对于所有连续的k−1k-1k−1个he ...
- Mybatis在oracle数据库中插入数据后返回自增值ID
1.将id设置成自增序列 CREATE OR REPLACE TRIGGER "DATALIB"."TRIG_USER_ADD" BEFORE INSERT O ...
- ubuntu彻底删除apache2 再重装
删除apache2不彻底,导致用 apt-get install apache2 重新装时总是不成功.下面是如何彻底删除apache2 1. 删除apache 代码: $ sudo apt-get - ...
- python3.4连接mysql5.7数据库增删改查
#!/usr/bin/env python # -*- coding:utf-8 -*- # __author__ = "blzhu" """ pyt ...
- 第01章:MongoDB简介
①MongoDB是什么 MongoDB是一个使用C++编写的.开源的.面向文档的NoSQL(Not Only SQL)数据库,也是当前最热门的NoSql数据库之一. ②MongoDB特点 1.高性能. ...
- python.csv 按行按列读取
参考:https://blog.csdn.net/ly_ysys629/article/details/55107237 # header=0,表示文件第0行为列索引 # index_col=0,表示 ...