欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

操作系统中的调度算法FCFS、SJF、RR算法(Java实现)

程序员文章站 2022-07-05 11:50:08
...

Proce类:
package five;

public class Process {
public String name;// 进程名称
public int arrivalTime;// 到达时间
public int serviceTime;// 服务时间
public int finishTime;// 完成时间
public int startTime;// 开始时间
public int WholeTime;// 周转时间
public double weightWholeTime;// 带权周转时间
private int remainServiceTime; // 还需要服务的时间

Process(int arrivalTime, int serviceTime, String name) {
	this.arrivalTime = arrivalTime;
	this.serviceTime = serviceTime;
	this.remainServiceTime = serviceTime;
	this.name = name;
}

//name的set()和get()
public String getName() {
return name;
}

public void setName(String name) {
	this.name = name;
}

//arrivalTime
public int getArrivalTime() {
return arrivalTime;
}

public void setArrivalTime(int arrivalTime) {
	this.arrivalTime = arrivalTime;
}

//ServiceTime
public int getServiceTime() {
return serviceTime;
}

public void setServiceTime(int serviceTime) {
	this.serviceTime = serviceTime;
}

//finishTime
public int getFinishTime() {
return finishTime;
}

public void setFinishTime(int finishTime) {
	this.finishTime = finishTime;
}

//startTime
public int getStartTime() {
return startTime;
}

public void setStartTime(int startTime) {
	this.startTime = startTime;
}

public int getWholeTime() {
	return WholeTime;
}

public void setWholeTime(int wholeTime) {
	WholeTime = wholeTime;
}

public double getWeightWholeTime() {
	return weightWholeTime;
}

public void setWeightWholeTime(double weightWholeTime) {
	this.weightWholeTime = weightWholeTime;
}

public int getRemainServiceTime() {
	return remainServiceTime;
}

public void setRemainServiceTime(int remainServiceTime) {
	this.remainServiceTime = remainServiceTime;
}

@Override
public String toString() {
	return "名称:" + name + "   到达时间:" + arrivalTime + "   服务时间:" + serviceTime;
}

}

RR算法的类:
4
package five;

import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.LinkedBlockingQueue;

public class RR {
private int ProcessCount; // 进程数
private Queue ReadyQueue; // 就绪队列,存放“待运行的进程
private Queue UnreachQueue; // 存放可执行的进程
private int TimeSlice; // 时间片

private Queue<Process> ExecutedQueue; // 执行完毕的进程队列
private double mTotalWholeTime = 0.0;
private double mTotalWeightWholeTime = 0.0;

public RR(int processCount, Queue<Process> processQueue, int timeSlice) {
	this.ProcessCount = processCount;
	this.UnreachQueue = processQueue;
	ReadyQueue = new LinkedBlockingQueue<>();
	this.TimeSlice = timeSlice;
	ExecutedQueue = new LinkedList<>();
}

private int executeProcess(Process currProcess, int currTime) {
	if (currProcess.getRemainServiceTime() - TimeSlice <= 0) {
		// 当前进程在这个时间片内能执行完毕
		showExecuteMessage(currTime, currTime += currProcess.getRemainServiceTime(), currProcess.getName());
		currProcess.setFinishTime(currTime);
		currProcess.setRemainServiceTime(0);
		// 对周转时间等进行计算
		calculeteWholeTime(currProcess);
		calculateWeightWholeTime(currProcess);
		mTotalWholeTime += currProcess.getWholeTime();
		mTotalWeightWholeTime += currProcess.getWeightWholeTime();
		ExecutedQueue.add(currProcess);// 加入完成队列
	} else {
		// 不能执行完毕
		showExecuteMessage(currTime, currTime += TimeSlice, currProcess.getName());
		currProcess.setRemainServiceTime(currProcess.getRemainServiceTime() - TimeSlice);// 更新该进程的剩余时间
	}
	return currTime;
}

/**
 * RR 算法实现
 */
public void RRAlgorithm() {
	ReadyQueue.add(UnreachQueue.poll());
	Process currProcess = ReadyQueue.poll();
	// 第一个进程执行
	int currTime = executeProcess(currProcess, 0);// 更新时间

	while (!ReadyQueue.isEmpty() || !UnreachQueue.isEmpty()) {
		// 把所有“到达时间”达到的进程加入运行队列头部
		while (!UnreachQueue.isEmpty()) {
			if (UnreachQueue.peek().getArrivalTime() <= currTime) {// 取队列头,比较是否到达
				ReadyQueue.add(UnreachQueue.poll());// 将可执行队列头部的元素移除并加到就绪队列
			} else {
				break;
			}
		}

		if (currProcess.getRemainServiceTime() > 0)// 未执行完毕,将该进程添加到队列尾
			ReadyQueue.add(currProcess);
		// 运行队列不为空时,继续操作下一个进程
		if (!ReadyQueue.isEmpty()) {

			currProcess = ReadyQueue.poll();

			currTime = executeProcess(currProcess, currTime);
		} else {
			// 当前没有进程执行,但还有进程未到达,时间直接跳转到到达时间
			currTime = UnreachQueue.peek().getArrivalTime();
		}
	}
}

/**
 * 计算周转时间
 * 
 * @param process
 */
private void calculeteWholeTime(Process process) {
	process.setWholeTime(process.getFinishTime() - process.getArrivalTime());
}

/**
 * 计算带权周转时间
 * 
 * @param process
 */
private void calculateWeightWholeTime(Process process) {
	process.setWeightWholeTime(process.getWholeTime() / (double) process.getServiceTime());
}

private void showExecuteMessage(int startTime, int endTime, String name) {
	System.out.println(startTime + "~" + endTime + ":【进程" + name + "】运行");
}

public void showResult() {
	System.out.print("进程名\t\t");
	System.out.print("完成时间\t\t");
	System.out.print("周转时间\t\t");
	System.out.println("带权周转时间\t");
	Process process;
	while (!ExecutedQueue.isEmpty()) {
		process = ExecutedQueue.poll();
		System.out.print("进程" + process.getName() + "\t");
		System.out.print("\t" + process.getFinishTime() + "\t");
		System.out.print("\t" + process.getWholeTime() + "\t");
		System.out.println("\t" + process.getWeightWholeTime() + "\t");
	}
	System.out.println("平均周转时间:" + mTotalWholeTime / (double) ProcessCount);
	System.out.println("平均带权周转时间:" + mTotalWeightWholeTime / (double) ProcessCount);
}

public static void printAll(Queue<Process> queue) {
	System.out.print("进程名\t\t");
	System.out.print("到达时间\t\t");
	System.out.println("服务时间\t");
	Process process = null;
	while (!queue.isEmpty()) {
		process = queue.poll();
		System.out.print("进程" + process.getName() + "\t");
		System.out.print("\t" + process.getArrivalTime() + "\t");
		System.out.println("\t" + process.getServiceTime() + "\t");
	}
}

}
主函数:
package five;

import java.text.DecimalFormat;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
import java.util.concurrent.LinkedBlockingQueue;

public class FiveMain {
public static void main(String[] args) {

	Process[] p = new Process[5];
	p[0] = new Process(0, 4, "A");
	p[1] = new Process(1, 3, "B");
	p[2] = new Process(2, 5, "C");
	p[3] = new Process(3, 2, "D");
	p[4] = new Process(4, 4, "E");

	Queue<Process> queue = new LinkedBlockingQueue<>();
	for (int i = 0; i < p.length; i++) {
		queue.add(p[i]);

	}
	Scanner in = new Scanner(System.in);
	while (true) {
		System.out.println("1:FCFS     2:SJF    3.RR       0:退出");
		switch (in.nextInt()) {
		case 1:
			System.out.println("*******************   FCFS   *****************");
			System.out.println("初始化5个进程ABCDE:");
			for (int i = 0; i < p.length; i++) {
				System.out.println(p[i].toString());
			}
			FCFS(p);
			print(p);

			break;
		case 2:
			System.out.println("*******************   SJF    *****************");
			System.out.println("初始化5个进程ABCDE:");
			for (int i = 0; i < p.length; i++) {
				System.out.println(p[i].toString());
			}
			Process[] processes = SJF(p);
			print(processes);
			break;
		case 3:
			System.out.println("*******************    RR    *****************");
			System.out.println("初始化5个进程ABCDE:");
			for (int i = 0; i < p.length; i++) {
				System.out.println(p[i].toString());
			}

			RR rr = new RR(5, queue, 1);

			System.out.println("******************运行过程*****************");

			rr.RRAlgorithm();

			System.out.println("*******************运行结果*****************");

			rr.showResult();
			break;
		
		case 0:
			// 退出
			System.exit(0);
			break;

		default:
			System.out.println("输入错误,请重新输入!");
			break;

		}

	}
}

// 插入排序
public static void InsertSort(Process[] array) {
	int i, j;
	int n = array.length;
	Process target;
	for (i = 1; i < n; i++) {
		j = i;
		target = array[i];
		while (j > 0 && target.arrivalTime < array[j - 1].arrivalTime) {
			array[j] = array[j - 1];
			j--;
		}
		array[j] = target;
	}
}

// FCFS算法
public static void FCFS(Process[] p) {
	InsertSort(p);
	for (int i = 0; i < p.length; i++) {
		if (i == 0) {
			p[i].finishTime = p[i].arrivalTime + p[i].serviceTime;
			p[i].startTime = p[i].arrivalTime;
		} else {
			if (p[i].arrivalTime > p[i - 1].finishTime) {
				p[i].finishTime = p[i].arrivalTime + p[i].serviceTime;
				p[i].startTime = p[i].arrivalTime;
			} else {
				p[i].finishTime = p[i - 1].finishTime + p[i].serviceTime;
				p[i].startTime = p[i - 1].finishTime;
			}

		}
		// 计算周转时间和带权周转时间
		p[i].WholeTime = p[i].finishTime - p[i].arrivalTime;
		p[i].weightWholeTime = (float) p[i].WholeTime / p[i].serviceTime;

	}

}

// 找出下一个处理的进程
public static Process FindNextPro(LinkedList<Process> list, int now) {
	Process process = list.get(0);
	int index = 0;
	for (int i = 1; i < list.size(); i++) {
		if (list.get(i).serviceTime < process.serviceTime && list.get(i).arrivalTime < now) {// 判断条件找到服务时间最短的进程并且已经到达
			process = list.get(i);
			index = i;

		}

	}
	list.remove(index);
	return process;
}

//SJF算法
public static Process[] SJF(Process[] p) {
// 待处理
LinkedList list = new LinkedList<>();
// 结果
LinkedList result = new LinkedList<>();
// 当前时间
int now = 0;
// 按到达时间排序
InsertSort§;
// 对第一个进程操作
p[0].finishTime = p[0].arrivalTime + p[0].serviceTime;
p[0].WholeTime = p[0].finishTime - p[0].arrivalTime;
p[0].weightWholeTime = (float) p[0].WholeTime / p[0].serviceTime;
// 添加到结果
result.add(p[0]);
// 更新时间
now = p[0].finishTime;
// 将剩余添加到待处理
for (int i = 1; i < p.length; i++) {
list.add(p[i]);

	}
	while (list.size() != 0) {
		Process next = FindNextPro(list, now);// 找到当前队列中服务时间最短的进程

		if (next.arrivalTime > now) {// 未到
			next.finishTime = next.arrivalTime + next.serviceTime;
			next.startTime = next.arrivalTime;

		} else {// 到达
			next.finishTime = now + next.serviceTime;
			next.startTime = now;

		}
		now = next.finishTime;// 更新时间
		next.WholeTime = next.finishTime - next.arrivalTime;
		next.weightWholeTime = (float) next.WholeTime / next.serviceTime;
		result.add(next);// 添加到结果队列

	}
	Process[] res = new Process[result.size()];

	return result.toArray(res);

}

public static void print(Process[] p) {
	DecimalFormat df = new DecimalFormat("#.00");
	float sumWT = 0;
	float sumWWT = 0;
	float AverageWT;
	float AverageWWT;
	for (int i = 0; i < p.length; i++) {
		System.out.println("时刻" + p[i].startTime + ":  进程" + p[i].name + "开始运行      完成时间为:" + p[i].finishTime
				+ "    周转时间为:" + p[i].WholeTime + "    带权周转时间为:" + df.format(p[i].weightWholeTime));
		sumWT += p[i].WholeTime;
		sumWWT += p[i].weightWholeTime;
	}
	AverageWT = sumWT / p.length;
	AverageWWT = sumWWT / p.length;

	System.out.println("平均周转时间为:" + df.format(AverageWT));
	System.out.println("平均带权周转时间为:" + df.format(AverageWWT));
	System.out.println("---------------------------------------------------------");
}

}