⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 banktest.java

📁 银行家算法
💻 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 + -