死锁是在我们的程序中出现了程序的嵌套锁导致的
死锁是一个错误
是多线程中很重要的一共知识点
示意图
B等着A释放锁
A等着B释放锁
介绍线程
线程是操作系统能够进行运算调度的最小单位,他被包含在进程之内,是进程中实际运作的单位
每一个线程都有独立的代码和数据空间
线程在执行代码的时候
线程在执行的时候 具有随机性
CPU的执行权随时有可能被其他的线程抢走
线程里有一个概念叫锁
当有线程进入时 锁会自动关闭
线程出去后锁会自动打开
如果有线程先拿到锁的对象 获取了CPU的执行权
其他的线程就算拿到CPU的执行权也会被关在外面
其他线程抢到CPU执行权后会发现无法获得锁的对象
此时锁已经关闭
死锁就是线程1,2各自拿到了锁A,B的对象
线程1,2得获取锁B,A的对象才能进入下一步
但是需要的锁对象被对方已经拿到了
代码实现
public class MyThread extends Thread{ //创建锁的对象 static Object objA=new Object(); static Object objB=new Object(); @Override public void run() { if("线程A".equals(getName())){ synchronized (objA){ System.out.println("线程A拿到了A锁"); synchronized (objB){ System.out.println("线程A拿到B锁,执行完毕"); } } } else if("线程B".equals(getName())){ synchronized (objB){ System.out.println("线程B拿到了B锁"); synchronized (objA){ System.out.println("线程B拿到了A锁,执行完毕"); } } } } }
public class Main { public static void main(String[] args) { MyThread t1 = new MyThread(); MyThread t2 = new MyThread(); t1.setName("线程A"); t2.setName("线程B"); t1.start(); t2.start(); } }
控制台显示
程序未停止运行
避免死锁的方法
- 加锁顺序: 确定所有线程获取锁的顺序,然后要求所有线程都按照相同的顺序获取锁。
- 超时机制: 确定一个超时时间,在尝试获取锁之后,如果超过一定时间还未能成功获取锁,则放弃当前的锁并释放已经获取的锁。
- 资源分配策略: 采用预防性分配资源策略,以最大限度地减少发生死锁的可能性。
- 死锁检测: 建立一个机制来检测系统中是否存在死锁,一旦检测到死锁,就采取相应的措施来解除死锁。
- 避免环路等待: 确保不存在循环等待的情况,例如通过给资源编号,要求线程必须按照递增的顺序请求资源。
银行家算法
一种操作系统基本算法
有人去银行借钱 应该说出借的钱的数量
而银行会根据借的数量 结合自己银行所拥有的财产放出借的钱
银行会在自己的能里范围内最大满足顾客的需求
现在有进程要进入系统 抢占CPU 系统会分析给予资源分配 否则让其等
银行家算法基本原理如下:
- 系统在运行时会为每个进程和资源分配一个最大需求量和当前已分配量。
- 当一个进程请求资源时,系统会先检查是否有足够的资源可以分配给该进程,如果有,则会尝试分配资源给该进程并检查是否会导致系统进入不安全状态。
- 如果分配资源给该进程不会导致系统进入不安全状态,那么就会分配资源给该进程;否则,系统会拒绝分配资源,直到系统处于安全状态。
通过使用银行家算法,系统可以有效地避免死锁情况的发生,保证系统资源的合理利用。
在这段代码中,首先用户需要输入进程数和资源数,然后输入最大需求矩阵、已分配矩阵和可用资源向量。接着程序会根据用户输入计算出需求矩阵。然后通过银行家算法的安全性检查,判断系统是否处于安全状态。
在 isSafe 方法中,程序会模拟系统对进程的资源请求和释放,并通过检查每次操作后系统是否仍然处于安全状态来判断系统整体是否处于安全状态。如果系统可以满足所有进程的资源请求并且不会发生死锁,则系统被认为是处于安全状态。
最后,在 main 方法中调用 isSafe 方法,根据返回的结果输出相应的信息,告知用户系统当前的安全状态。
import java.util.Scanner; public class BankersAlgorithm { private int[][] maximum; // 最大需求矩阵 private int[][] allocation; // 已分配矩阵 private int[][] need; // 需求矩阵 private int[] available; // 可用资源向量 private int numberOfProcesses; // 进程数 private int numberOfResources; // 资源数 // 初始化资源信息 public void initializeData() { Scanner scanner = new Scanner(System.in); System.out.println("Enter number of processes:"); numberOfProcesses = scanner.nextInt(); System.out.println("Enter number of resources:"); numberOfResources = scanner.nextInt(); maximum = new int[numberOfProcesses][numberOfResources]; allocation = new int[numberOfProcesses][numberOfResources]; need = new int[numberOfProcesses][numberOfResources]; available = new int[numberOfResources]; // 输入最大需求矩阵 System.out.println("Enter maximum matrix:"); for (int i = 0; i < numberOfProcesses; i++) { for (int j = 0; j < numberOfResources; j++) { maximum[i][j] = scanner.nextInt(); } } // 输入已分配矩阵 System.out.println("Enter allocation matrix:"); for (int i = 0; i < numberOfProcesses; i++) { for (int j = 0; j < numberOfResources; j++) { allocation[i][j] = scanner.nextInt(); // 计算需求矩阵 need[i][j] = maximum[i][j] - allocation[i][j]; } } // 输入可用资源向量 System.out.println("Enter available vector:"); for (int i = 0; i < numberOfResources; i++) { available[i] = scanner.nextInt(); } scanner.close(); } // 银行家算法检查系统是否处于安全状态 public boolean isSafe() { boolean[] finish = new boolean[numberOfProcesses]; int[] work = new int[numberOfResources]; // 初始化 work 数组 for (int i = 0; i < numberOfResources; i++) { work[i] = available[i]; } // 初始化 finish 数组 for (int i = 0; i < numberOfProcesses; i++) { finish[i] = false; } int count = 0; while (count < numberOfProcesses) { boolean found = false; for (int i = 0; i < numberOfProcesses; i++) { if (!finish[i]) { int j; for (j = 0; j < numberOfResources; j++) { if (need[i][j] > work[j]) { break; } } if (j == numberOfResources) { // 如果进程可以被满足 for (int k = 0; k < numberOfResources; k++) { work[k] += allocation[i][k]; } finish[i] = true; found = true; count++; } } } if (!found) { return false; // 无法满足某个进程的需求 } } return true; // 所有进程均可以满足 } public static void main(String[] args) { BankersAlgorithm bankersAlgorithm = new BankersAlgorithm(); bankersAlgorithm.initializeData(); if (bankersAlgorithm.isSafe()) { System.out.println("System is in safe state."); } else { System.out.println("System is in unsafe state."); } } }