java模拟实现操作系统进程调度中的多级反馈队列算法

java模拟实现操作系统进程调度中的多级反馈队列算法

操作系统学了一学期了,期末作业布置下来,用编程语言模拟进程调度的过程,只会java,于是就写了一下,通过控制台模拟,模拟过程看起来可能十分不直观。试了几个例子,发现没有错误。

注释很详细,直接粘上代码

代码

MainTest.java 主方法

package 多级反馈队列算法;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Scanner;

public class MainTest {
	public static void main(String[] args) {
		LevelQueue<Process> Level1Queue = new LevelQueue<Process>(1, 1); // 一级队列,轮转时间片为1
		LevelQueue<Process> Level2Queue = new LevelQueue<Process>(2, 2); // 二级队列,轮转时间片为2
		LevelQueue<Process> Level3Queue = new LevelQueue<Process>(3, 4); // 三级队列,轮转时间片为4
		LevelQueue<Process> Level4Queue = new LevelQueue<Process>(4, 999); // 四级队列,轮转时间片为999(认为是无限大)
		List<Process> processes = new ArrayList<Process>(); // 存储初始化准备进程的ArrayList
		int[] arrivalTime; // 进程到达时间数组
		int currentTime = 0; // 存储当前时间
		int processSum; // 总进程数
		int processRemaining; // 剩余进程数

		// 初始化进程信息

		Scanner sc = new Scanner(System.in);
		System.out.println("先输入总进程数, 再依次输入各个进程的到达时间和服务时间");
		processSum = sc.nextInt();
		processRemaining = processSum;
		arrivalTime = new int[processSum];// 初始化到达时间数组
		for (int i = 0; i < processSum; i++) {
			int a = sc.nextInt(); // 到达时间
			int s = sc.nextInt(); // 服务时间
			Process p = new Process("P" + i, a, s);
			arrivalTime[i] = a;
			processes.add(p);
		}
		sc.close();
		// //返回当前用户输入的数据
		// Iterator it = processes.iterator();
		// while (it.hasNext()){
		// Process p = (Process)it.next();
		// System.out.println(p.toString());
		// }
		Process.ifAllCompleted(); // 输出当前进程数

		// 将进程按照到达时间顺序进行排序 并获得到达时间数组

		for (int i = 0; i < processSum; i++) {
			for (int j = i + 1; j < processSum; j++) {
				Process p1 = (Process) processes.get(i);
				Process p2 = (Process) processes.get(j);
				if (p2.arrivalTime < p1.arrivalTime) {
					processes.set(i, p2);
					processes.set(j, p1);
					arrivalTime[i] = p2.arrivalTime;
					arrivalTime[j] = p1.arrivalTime;

				} else if (p2.arrivalTime == p1.arrivalTime) { // 若同时到达 则短作业优先
					if (p2.serviceTime < p1.serviceTime) {
						processes.set(i, p2);
						processes.set(j, p1);
						arrivalTime[i] = p2.arrivalTime;
						arrivalTime[j] = p1.arrivalTime;
					} else if (p2.serviceTime == p1.serviceTime) { // 若服务时间也相等,则将p2放在p1后面,并将p1后面的进程和p2交换
						Process tmp = (Process) processes.get(i + 1);
						processes.set(i + 1, p2);
						processes.set(j, tmp);
						arrivalTime[i + 1] = p2.arrivalTime;
						arrivalTime[j] = tmp.arrivalTime;
					}
				}

			}
		}
		// 验证 排序是否正确
		Iterator<Process> it2 = processes.iterator();
		while (it2.hasNext()) {
			Process p = (Process) it2.next();
			System.out.println(p.toString());
		}
		for (int i = 0; i < arrivalTime.length; i++) {
			System.out.println(arrivalTime[i]);
		}
		// 开始模拟运行

		int position = 0;// 记录当前运行的进程位置,从0第一个进程开始
		while (true) {
			// 首先判断是否有新的作业到达
			if (position < processSum) { // 若大于等于进程总数则证明全部入队
				if (arrivalTime[position] <= currentTime) { // 取出数组第一个进程的到达时间与当前时间进行比较
															// ,若等于或者小于当前时间,
															// 说明有程序到达并进入第一队列

					Process p = (Process) processes.get(position);
					Level1Queue.add(p); // 进程入一级队列
					System.out.println(p.name + "进程于" + p.arrivalTime + "时间,加入一级队列");
					if (position == 0) { // 若是第一个到达并开始的作业,则更新当前时间为其到达时间
						currentTime = p.arrivalTime;
					}
					System.out.println("当前时间:" + currentTime);
					p.queue = Level1Queue; // 为进程初始化当前所在队列信息
					position++;
				}
			} else {
				if (Process.ifAllCompleted()) { // 如果所有进程完毕则退出循环
					break;
				}
			}

			if (!Level1Queue.isEmpty()) // 若一级队列非空,则优先执行一级队列
			{
				Process p = Level1Queue.peek();
				if (p.serviceTime <= Level1Queue.timeSlice) { // 如果队头进程服务时间小于等于该队列时间片。
																// 则进程完成
					p.Finished(); // 进程结束 并自动出队
					processRemaining -= 1; // 进程总数-1
				} else {
					// 一级出队并打入下一级队列
					Level1Queue.poll();
					p.excutedTime += Level1Queue.timeSlice; // 更新进程的运行时间
					p.queue = Level2Queue; // 为进程更新当前所在队列信息
					Level2Queue.add(p); // 进入二级队列
				}

				// 更新时间 判断是否完成所有进程
				currentTime += Level1Queue.timeSlice; // 当前时间等于执行前时间加上当前队列时间片
				System.out.println("当前时间:" + currentTime);
				if (Process.ifAllCompleted()) { // 如果所有进程完毕则退出循环
					break;
				}

			} else if (!Level2Queue.isEmpty()) // 若一级队列为空,二级队列非空,则优先执行二级队列
			{
				Process p = Level2Queue.peek();
				int timeRemaining = p.serviceTime - p.excutedTime; // 进程剩余时间
				if (timeRemaining <= Level2Queue.timeSlice) { // 如果队头进程服务时间小于等于该队列时间片。
					// 则进程完成
					p.Finished(); // 进程结束 并自动出队
					processRemaining -= 1; // 进程总数-1

					// 更新时间 判断是否完成所有进程
					currentTime += timeRemaining; // 当前时间等于执行前时间加上当前队列时间片
					System.out.println("当前时间:" + currentTime);
					if (Process.ifAllCompleted()) { // 如果所有进程完毕则退出循环
						break;
					}

				} else {
					// 二级出队并打入下一级队列
					Level2Queue.poll();
					p.excutedTime += Level2Queue.timeSlice; // 更新进程的运行时间
					p.queue = Level3Queue; // 为进程更新当前所在队列信息
					Level3Queue.add(p); // 进入三级队列

					// 更新时间 判断是否完成所有进程
					currentTime += Level2Queue.timeSlice; // 当前时间等于执行前时间加上当前队列时间片
					System.out.println("当前时间:" + currentTime);
					if (Process.ifAllCompleted()) { // 如果所有进程完毕则退出循环
						break;
					}
				}

			} else if (!Level3Queue.isEmpty()) // 若二级队列为空,执行三级队列
			{
				Process p = Level3Queue.peek();
				int timeRemaining = p.serviceTime - p.excutedTime; // 进程剩余时间
				if (timeRemaining <= Level3Queue.timeSlice) { // 如果队头进程服务时间小于等于该队列时间片。
					// 则进程完成
					p.Finished(); // 进程结束 并自动出队
					processRemaining -= 1; // 进程总数-1

					// 更新时间 判断是否完成所有进程
					currentTime += timeRemaining; // 当前时间等于执行前时间加上当前队列时间片
					System.out.println("当前时间:" + currentTime);
					if (Process.ifAllCompleted()) { // 如果所有进程完毕则退出循环
						break;
					}
				} else {
					// 三级出队并打入下一级队列
					Level3Queue.poll();
					p.excutedTime += Level3Queue.timeSlice; // 更新进程的运行时间
					p.queue = Level4Queue; // 为进程更新当前所在队列信息
					Level4Queue.add(p); // 进入三级队列

					// 更新时间 判断是否完成所有进程
					currentTime += Level3Queue.timeSlice; // 当前时间等于执行前时间加上当前队列时间片
					System.out.println("当前时间:" + currentTime);
					if (Process.ifAllCompleted()) { // 如果所有进程完毕则退出循环
						break;
					}
				}
			} else if (!Level4Queue.isEmpty()) { // 最后执行四级队列
				Process p = Level4Queue.peek();
				int timeRemaining = p.serviceTime - p.excutedTime; // 进程剩余时间
				Process.ifAllCompleted();
				p.Finished(); // 进程结束 并自动出队
				processRemaining -= 1; // 进程总数-1
				currentTime += timeRemaining; // 当前时间等于执行前时间加上当前队列时间片
				System.out.println("当前时间:" + currentTime);
				if (Process.ifAllCompleted()) { // 如果所有进程完毕则退出循环
					break;
				}
			}
			System.out.println(processRemaining);
		}

	}
}

LevelQueue.java 等级队列类

package 多级反馈队列算法;

public class LevelQueue<T> implements Queue<Process> {
	protected Node<Process> front, rear;// front 和rear 分别指向队头和队尾节点
	protected int levelOfQueue; // 队列等级 1,2,3
	protected int timeSlice; // 队列时间片 1,2,4
	protected int account = 0; // 队列中排队的进程数

	public LevelQueue(int levelOfQueue, int timeSlice) { // 构造队列
		super();
		this.levelOfQueue = levelOfQueue;
		this.timeSlice = timeSlice;
	}

	@Override
	public boolean isEmpty() { // 判断队列是否为空 若为空返回true
		// TODO Auto-generated method stub
		if (this.front == null && this.rear == null) {
			System.out.println(this.levelOfQueue + "级队列当前没有进程正在运行");
			return true;
		} else {
			System.out.println(this.levelOfQueue + "级队列当前有" + this.account + "个进程正在运行");
			return false;
		}

	}

	@Override
	public boolean add(Process x) // 入队操作
	{
		// TODO Auto-generated method stub

		if (x == null) {
			return false; // 元素x 入队 空对象不能入队
		}
		// 进程到达cpu
		Node<Process> q = new Node<Process>(x, null); // 局部变量q接收数据内容。
		if (this.front == null) {
			this.front = q; // 空队插入
			account++;
		} else {
			this.rear.next = q; // 队列尾插入
			account++;
		}
		this.rear = q; // 尾指针位置更新
		return true; // 插入成功

	}

	@Override // 返回队头操作
	public Process peek() {
		// TODO Auto-generated method stub
		// 只返回队头元素,不进行任何操作,若队列为空则返回null;
		return this.isEmpty() ? null : this.front.data;
	}

	@Override
	public Process poll() { // 出队操作 返回队头元素,若队列为空返回 null
		// TODO Auto-generated method stub
		if (isEmpty()) {
			return null;
		}
		Process x = this.front.data; // 取得队头元素
		this.front = this.front.next; // 删除队头元素
		if (this.front == null) {
			this.rear = null;
		}
		account--;
		return x;
	}

}

Node.java 队列节点类

package 多级反馈队列算法;

public class Node<T> // 链式队列节点类
{
	public Process data; // 数据域 存储数据元素
	public Node<Process> next; // 地址域,引用后继节点

	public Node(Process data, Node<Process> next) {
		super();
		this.data = data;
		this.next = next;
	}

	public Node() {
		super();
	}

	/*
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		// TODO Auto-generated method stub
		return this.data.toString();
	}

}

Process.java 进程类

package 多级反馈队列算法;

public class Process // 进程类
{
	static int amountOfProcess = 0; // 所有进程总数

	protected String name; // 进程名
	protected int arrivalTime; // 进程到达内存的时间
	protected int serviceTime; // 进程完成需要占用cpu的服务时间
	protected int excutedTime = 0; // 进程已经执行时间
	protected LevelQueue<Process> queue = null; // 当前进程所在队列

	public Process(String name, int arrivalTime, int serviceTime) {
		super();
		this.name = name;
		this.arrivalTime = arrivalTime;
		this.serviceTime = serviceTime;
		amountOfProcess += 1;// 每创建一个进程对象,进程总数+1
	}

	public void Finished() { // 进程结束
		// 执行出队操作
		queue.poll();
		System.out.println("-------------------");
		System.out.println("进程:" + this.name + "执行完毕,结束时位于第" + this.queue.levelOfQueue + "队列。");
		System.out.println(this.toString());
		amountOfProcess -= 1;// 每完成一个进程对象,进程总数-1
	}

	@Override
	public String toString() {
		// TODO Auto-generated method stub
		if (queue != null) {
			return "进程:" + this.name + ",到达时间:" + this.arrivalTime + ",服务时间" + this.serviceTime + ",进程已经执行时间:"
					+ this.excutedTime + ",进程当前所在队列" + queue.levelOfQueue + "。";
		} else {
			return "进程:" + this.name + ",到达时间:" + this.arrivalTime + ",服务时间" + this.serviceTime;
		}
	}

	public static boolean ifAllCompleted() {
		if (amountOfProcess == 0) {
			System.out.println("当前没有进程正在运行");
			return true;
		} else {
			System.out.println("当前有" + amountOfProcess + "个进程等待运行。");
			return false;
		}

	}
}

Queue.java

package 多级反馈队列算法;

public interface Queue<T>		//队列接口类 
{	
	public abstract boolean isEmpty();
	public abstract boolean add(T x);//添加成功返回true
	public abstract T peek();  //返回队头元素,若为空返回null

	public abstract T poll(); // 出队,并返回队头元素,若为空返回null
}

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值