我们设置了一系列描述进程的参数,并提供一个构造函数用于初始化进程。
public class JCB {
String name;//进程名
int arriveTime;//到达时间
int serveTime;//服务时间
int beginTime;//开始时间
int finshTime;//结束时间
int roundTime;//周转时间
int waitTime;//等待时间
double aveRoundTime;//带权周转时间
double clock=0;//已经服务运行的时间
boolean firstTimeTag=false;//在RR算法中标识开始时间是否第一次计算
public JCB() {
}
public JCB(String name, int arriveTime, int serveTime) {
super();
this.name = name;
this.arriveTime = arriveTime;
this.serveTime = serveTime;
this.waitTime = 0;
}
public String toString() {
String info=new String("进程名:P"+this.name);
return info;
}
}
本节我们首先创建三个数组链表,用于存储各个状态的进程JCB
ArrayList
jcb;// 存放所有进程
LinkedListlink;// 存放已经进入队列的进程
ArrayListnew_jcb;// 存放按指定调度算法排序后的进程
对进程初始化,这里我设置了进程的参数,其实顺便设置都行。
public void init() {//初始化
jcb = new ArrayList();
link = new LinkedList();
new_jcb = new ArrayList();
JCB p1 = new JCB("1", 0, 4);
JCB p2 = new JCB("2", 1, 3);
JCB p3 = new JCB("3", 2, 5);
JCB p4 = new JCB("4", 3, 2);
JCB p5 = new JCB("5", 4, 4);
jcb.add(p1);
jcb.add(p2);
jcb.add(p3);
jcb.add(p4);
jcb.add(p5);
}
根据算法实现原理,我们可以知道除了时间片轮转算法RR的进程执行方法不一样之外,其他的FCFS、SJF和HRRN的方法一样,都只是在执行之前根据要求对link里面的JCB进程按照各自的算法进行排序,所以他们共用一个Dequeue方法,对于RR我们通过对Dequeue重写,提供参数(时间片)来控制。
并且在进程的执行过程中我们还需要更新当前时间、其他进程的等待时间、进程的完成时间,还需要计算周转时间等参数。
排序的算法,我们通过Collections的sort方法实现,但是我们需要重写一个类继承sort方法的参数Comparator,实现按照我们需要的算法要求对JCB排序。
对于RR算法,唯一需要注意的是在每次使用完时间片的时候要注意更新时间。
package rjxy.xju;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.Scanner;
public class processMenu {
ArrayList jcb;// 存放所有进程
LinkedList link;// 存放已经进入队列的进程
ArrayList new_jcb;// 存放按指定调度算法排序后的进程
JCB nowProess;// 当前应执行进程
public void init() {//初始化
jcb = new ArrayList();
link = new LinkedList();
new_jcb = new ArrayList();
JCB p1 = new JCB("1", 0, 4);
JCB p2 = new JCB("2", 1, 3);
JCB p3 = new JCB("3", 2, 5);
JCB p4 = new JCB("4", 3, 2);
JCB p5 = new JCB("5", 4, 4);
jcb.add(p1);
jcb.add(p2);
jcb.add(p3);
jcb.add(p4);
jcb.add(p5);
}
public void FCFS(){//先来先服务算法
ProcessQueue pq=new ProcessQueue();
pq.EnqueueLast();//进程入队
System.out.println("*****************************************************");
while(!link.isEmpty()) {
pq.DisplayQueue();//打印当前队列中的进程
pq.Dequeue();//出队
pq.EnqueueLast();//进程入队
Collections.sort(link, new compareAt_St());
}
}
public void SJF() {
ProcessQueue pq=new ProcessQueue();
pq.EnqueueLast();
System.out.println("*****************************************************");
while(!link.isEmpty()) {
pq.DisplayQueue();
pq.Dequeue();
pq.EnqueueLast();
Collections.sort(link,new compareSt());
}
}
public void HRRN() {
ProcessQueue pq=new ProcessQueue();
pq.EnqueueLast();
System.out.println("*****************************************************");
while(!link.isEmpty()) {
pq.DisplayQueue();
pq.Dequeue();
pq.EnqueueLast();
Collections.sort(link,new compareRt());
}
}
public void RR() {
ProcessQueue pq=new ProcessQueue();
pq.EnqueueLast();
System.out.println("*****************************************************");
while(!link.isEmpty()) {
pq.DisplayQueue();//打印当前队列中的进程
pq.Dequeue(1);//出队
}
}
class ProcessQueue{
int k = 0;// jcb中的进程遍历时的下标
int nowTime = 0;// 当前时间
int i=0;//记录当前出入队列的次数
public void EnqueueLast() {
while (k < jcb.size()) {//遍历jcb
if (jcb.get(k).arriveTime <= nowTime) {//已经到达的进程按到达时间先后进入队列
link.addLast(jcb.get(k));
k++;
} else {
break;
}
}
}
public void EnqueueFirst() {//进程入队
while (k < jcb.size()) {//遍历jcb
if (jcb.get(k).arriveTime <= nowTime) {//已经到达的进程按到达时间先后进入队列
link.addFirst(jcb.get(k));
k++;
} else {
break;//如果该进程还未入队,即先结束遍历,保留当前下标k值,注意:此处不要k--;
}
}
}
public void Dequeue() {//进程出队,一次只出一个
nowProess = link.removeFirst();//移除队列的队首元素并且返回该对象元素
nowProess.beginTime = nowTime;//计算开始时间,即为上一个进程的结束时间
nowProess.finshTime = nowProess.beginTime + nowProess.serveTime;//计算结束时间,该进程开始时间+服务时间
nowProess.roundTime = nowProess.finshTime;//计算周转时间
nowProess.aveRoundTime = (double) nowProess.roundTime / nowProess.serveTime;//计算平均周转时间
nowTime = nowProess.finshTime;//获得结束时间,即当前时间,方便判断剩下的进程是否已到达
new_jcb.add(nowProess);//经处理过数据后加入new_jcb容器
for(int i=0;i=nowProess.serveTime) {
nowProess.finshTime=nowTime;//计算该进程完成时间
nowProess.roundTime = nowProess.finshTime - nowProess.arriveTime;//计算周转时间
nowProess.aveRoundTime = (double) nowProess.roundTime / nowProess.serveTime;//计算平均周转时间
new_jcb.add(nowProess);
EnqueueFirst();//已到达的进程先入队
}
else {
EnqueueFirst();//已到达的进程先入队
link.addLast(nowProess);//上一轮出的再紧接着进入队尾
}
}
public void DisplayQueue(){//打印队列中等候的进程
i++;
System.out.println("第"+i+"次队列中排队的进程:"+link);
}
}
public void printProcess() {
System.out.println("进程名\t到达时间\t服务时间\t开始时间\t完成时间\t周转时间\t带权周转时间");
for (int i = 0; i < new_jcb.size(); ++i) {
System.out.println("P"+new_jcb.get(i).name + "\t" + new_jcb.get(i).arriveTime + "\t" +
new_jcb.get(i).serveTime+ "\t" + new_jcb.get(i).beginTime + "\t" + new_jcb.get(i).finshTime +
"\t"+ new_jcb.get(i).roundTime + "\t" + new_jcb.get(i).aveRoundTime);
}
new_jcb.clear();//清空new_jcb
}
}
class compareAt_St implements Comparator {// 按到达时间升序,若到达时间相同,按服务时间升序
public int compare(JCB o1, JCB o2) {
int a = o1.arriveTime - o2.arriveTime;
if (a > 0)
return 1;
else if (a == 0) {
return o1.serveTime > o2.serveTime ? 1 : -1;
} else
return -1;
}
}
class compareSt implements Comparator{
@Override
public int compare(JCB o1, JCB o2) {
// TODO 自动生成的方法存根
return o1.serveTime >= o2.serveTime ? 1 : -1;
}
}
class compareRt implements Comparator{
@Override
public int compare(JCB o1, JCB o2) {
// TODO 自动生成的方法存根
double r1=(double) (o1.waitTime+o1.serveTime)/o1.serveTime;
double r2=(double) (o2.waitTime+o2.serveTime)/o2.serveTime;
return r1
package rjxy.xju;
public class TestProcess {
public static void main(String[] args) {
processMenu pm=new processMenu();
pm.init();//初始化容器
pm.FCFS();
pm.printProcess();
pm.SJF();
pm.printProcess();
pm.HRRN();
pm.printProcess();
pm.RR();
pm.printProcess();
}
}