📄 banktest.java
字号:
package bankpackage;
import javax.swing.SwingUtilities;
import javax.swing.JPanel;
import javax.swing.JFrame;
import javax.swing.JLabel;
import java.awt.Rectangle;
import javax.swing.SwingConstants;
import java.awt.Font;
import java.awt.Color;
import java.util.*;
import javax.swing.BorderFactory;
import javax.swing.border.BevelBorder;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JButton;
public class BankTest extends JFrame {
private static final long serialVersionUID = 1L;
private JPanel jContentPane = null;
private JLabel jLabel = null;
private JScrollPane jScrollPane = null;
JTextArea jTextArea = null;
private JButton jButton = null;
private JButton jButton1 = null;
static int type = 4, num = 10; // 定义资源数目和线程数目
static int[] resource = new int[type]; // 系统资源总数
// static int[] copyResource = new int[type]; //副本
static Random rand = new Random();
static Bank[] bank = new Bank[num]; // 线程组
Bank temp = new Bank();
String strTemp=""; // @jve:decl-index=0:
private JButton jButton2 = null;
/**
* This method initializes jScrollPane
*
* @return javax.swing.JScrollPane
*/
private JScrollPane getJScrollPane() {
if (jScrollPane == null) {
jScrollPane = new JScrollPane();
jScrollPane.setBounds(new Rectangle(-1, 41, 566, 215));
jScrollPane.setViewportView(getJTextArea());
jScrollPane.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED));
}
return jScrollPane;
}
/**
* This method initializes jTextArea
*
* @return javax.swing.JTextArea
*/
private JTextArea getJTextArea() {
if (jTextArea == null) {
jTextArea = new JTextArea();
jTextArea.setLineWrap(true);
}
return jTextArea;
}
/**
* This method initializes jButton
*
* @return javax.swing.JButton
*/
private JButton getJButton() {
if (jButton == null) {
jButton = new JButton();
jButton.setBounds(new Rectangle(105, 275, 77, 26));
jButton.setText("开始");
jButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent e) {
init();
}
});
}
return jButton;
}
public void init() {
// 初始化组中每个线程,随机填充系统资源总数
for (int i = 0; i < type; i++)
resource[i] = rand.nextInt(10) + 80;
jTextArea.append("资源:");
for (int i = 0; i < type; i++)
jTextArea.append(" " + resource[i]);
jTextArea.append("\n");
for (int i = 0; i < bank.length; i++)
bank[i] = new Bank("进程" + i);
}
/**
* This method initializes jButton1
*
* @return javax.swing.JButton
*/
private JButton getJButton1() {
if (jButton1 == null) {
jButton1 = new JButton();
jButton1.setBounds(new Rectangle(413, 275, 77, 26));
jButton1.setText("关闭");
jButton1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent e) {
// TODO Auto-generated Event stub actionPerformed()
System.exit(0);
}
});
}
return jButton1;
}
/**
* This method initializes jButton2
*
* @return javax.swing.JButton
*/
private JButton getJButton2() {
if (jButton2 == null) {
jButton2 = new JButton();
jButton2.setBounds(new Rectangle(249, 275, 103, 27));
jButton2.setText("显示过程");
jButton2.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent e) {
jTextArea.append("\n"+strTemp);
}
});
}
return jButton2;
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO 自动生成方法存根
SwingUtilities.invokeLater(new Runnable() {
public void run() {
BankTest thisClass = new BankTest();
thisClass.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
thisClass.setVisible(true);
}
});
}
/**
* This is the default constructor
*/
public BankTest() {
super();
initialize();
}
/**
* This method initializes this
*
* @return void
*/
private void initialize() {
this.setSize(572, 344);
this.setContentPane(getJContentPane());
this.setTitle("银行家算法");
}
/**
* This method initializes jContentPane
*
* @return javax.swing.JPanel
*/
private JPanel getJContentPane() {
if (jContentPane == null) {
jLabel = new JLabel();
jLabel.setBounds(new Rectangle(0, 0, 566, 42));
jLabel.setHorizontalAlignment(SwingConstants.CENTER);
jLabel.setFont(new Font("Dialog", Font.BOLD, 18));
jLabel.setForeground(new Color(215, 33, 33));
jLabel.setBackground(Color.blue);
jLabel.setBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED));
jLabel.setText("银 行 家 算 法");
jContentPane = new JPanel();
jContentPane.setLayout(null);
jContentPane.add(jLabel, null);
jContentPane.add(getJScrollPane(), null);
jContentPane.add(getJButton(), null);
jContentPane.add(getJButton1(), null);
jContentPane.add(getJButton2(), null);
}
return jContentPane;
}
class Bank extends Thread {
// 银行家算法避免死锁
public int[] max = new int[type], // 总共需求量
need = new int[type], // 尚需资源量
allocation = new int[type]; // 已分配量
private int[] request = new int[type], // 申请资源量
copyResource = new int[type]; // 资源副本
private boolean isFinish = false; // 线程是否完成
int[][] table = new int[bank.length][type * 4]; // 二维资源分配表
private void init() {
// 随机填充总共、尚需、已分配量
synchronized (resource) {
for (int i = 0; i < type; i++) {
max[i] = rand.nextInt(5) + 10;
need[i] = rand.nextInt(10);
allocation[i] = max[i] - need[i];
resource[i] -= allocation[i]; // 从系统资源中减去已分配的
}
printer();
for (int i = 0; i < type; i++) {
if (resource[i] < 0) {
// 若出现已分配量超出系统资源总数的错误则退出
jTextArea.append("所有进程分配量超出了系统总资源数!\n");
}
}
}
}
public Bank(String s) {
setName(s);
init();
start();
}
public Bank() {
// none
}
public void run() {
try {
sleep(rand.nextInt(2000));
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
while (true) {
// 程序没有完成时一直不断申请资源
if (askFor() == false) {
try {
sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
} else
tryRequest();
if (noNeed() == true)
break;
}
// 休眠一段时间模拟程序运行
try {
sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
jTextArea.append(getName() + " 完成!\n");
strTemp=strTemp+"->"+getName();
synchronized (resource) {
// 运行结束释放占有资源
for (int i = 0; i < type; i++) {
resource[i] += allocation[i];
need[i] = allocation[i] = max[i] = 0;
}
}
}
private void printer() {
// 打印当前资源信息
jTextArea.append(getName() + " 最大需求量:");
for (int i = 0; i < type; i++)
jTextArea.append(" " + max[i]);
jTextArea.append(" 已分配资源:");
for (int i = 0; i < type; i++)
jTextArea.append(" " + allocation[i]);
jTextArea.append(" 还需要资源:");
for (int i = 0; i < type; i++)
jTextArea.append(" " + need[i]);
jTextArea.append(" 可用资源量:");
for (int i = 0; i < type; i++)
jTextArea.append(" " + resource[i]);
jTextArea.append("\n");
}
private boolean askFor() {
// 随机产生申请资源量并检测是否超标
boolean canAsk = false;
for (int i = 0; i < type; i++) {
request[i] = rand.nextInt(20);
// 防止申请量超过所需量
if (request[i] > need[i])
request[i] = need[i];
}
for (int i = 0; i < type; i++)
// 防止随机申请资源全为0
if (request[i] > 0)
canAsk = true;
synchronized (resource) {
// 锁住可供资源检查是否超标
for (int i = 0; i < type; i++) {
if (request[i] > resource[i])
// 如果申请资源超过可供资源则等待一段时间后重新申请
return false;
}
}
return canAsk;
}
private void tryRequest() {
// 创建副本尝试分配请求
synchronized (resource) {
for (int i = 0; i < type; i++)
// 依然要防止请求量超出范围
if (request[i] > resource[i])
return;
for (int i = 0; i < type; i++) {
// 复制资源量并减去需求量到一个副本上
copyResource[i] = resource[i];
copyResource[i] -= request[i];
}
jTextArea.append(getName() + " 请求资源:");
for (int i = 0; i < type; i++)
jTextArea.append(" " + request[i]);
jTextArea.append("\n");
if (checkSafe() == true) {
// 如果检查安全则将副本值赋给资源量并修改占有量和需求量
for (int i = 0; i < type; i++) {
resource[i] = copyResource[i];
allocation[i] += request[i];
need[i] -= request[i];
}
jTextArea.append(getName() + " 请求成功!\n");
} else
jTextArea.append(getName() + " 请求失败!\n");
}
}
private boolean checkSafe() {
// 银行家算法检查安全性
synchronized (bank) {
// 将线程资源信息放入二维资源分配表检查安全性,0~type可用资源/type~type*2所需资源/type*2~type*3占有资源/type*3~-1可用+占用资源
for (int i = 0; i < bank.length; i++) {
for (int j = type; j < type * 2; j++) {
table[i][j] = bank[i].need[j % type];
}
for (int j = type * 2; j < type * 3; j++) {
table[i][j] = bank[i].allocation[j % type];
}
}
// 冒泡排序按需求资源从小到大排
for (int i = 0; i < bank.length; i++) {
for (int j = i; j < bank.length - 1; j++) {
sort(j, 4);
}
}
// 进行此时刻的安全性检查
for (int i = 0; i < type; i++) {
table[0][i] = copyResource[i];
table[0][i + type * 3] = table[0][i]
+ table[0][i + type * 2];
if (table[0][i + type * 3] < table[1][i + type])
return false;
}
for (int j = 1; j < bank.length - 1; j++) {
for (int k = 0; k < type; k++) {
table[j][k] = table[j - 1][k + type * 3];
table[j][k + type * 3] = table[j][k]
+ table[j][k + type * 2];
if (table[j][k + type * 3] < table[j + 1][k + type])
return false;
}
}
}
return true;
}
private void sort(int j, int k) {
// 递归冒泡排序
int tempNum;
if (table[j][k] > table[j + 1][k]) {
for (int i = type; i < type * 2; i++) {
tempNum = table[j][i];
table[j][i] = table[j + 1][i];
table[j + 1][i] = tempNum;
}
/*
* temp = bank[j]; bank[j] = bank[j+1]; bank[j+1] = temp;
*/
} else if (table[j][k] == table[j + 1][k] && k < type * 2) // 此资源量相同时递归下一个资源量排序并且防止超出范围
sort(j, k + 1);
}
private boolean noNeed() {
// 是否还需要资源
boolean finish = true;
for (int i = 0; i < type; i++) {
if (need[i] != 0) {
finish = false;
break;
}
}
return finish;
}
}
} // @jve:decl-index=0:visual-constraint="10,10"
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -