import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
class PCB {
String name;//进程名
int arriveTime;//到达时间
int serveTime;//服务时间
int beginTime;//开始时间
int finshTime;//结束时间
int roundTime;//周转时间
int priority;//优先权
String processState = "W";//进程状态
double aveRoundTime;//带权周转时间
int cpuTime =0;//在时间轮转调度算法中,记录该进程真实服务时间已经用时的时长
int waitTime;//记录每个进程到达后的等待时间,只用于最高响应比优先调度算法中
boolean firstTimeTag=false;//在RR算法中标识开始时间是否第一次计算
public PCB() {
}
public PCB(String name,int priority, int arriveTime, int serveTime,int cpuTime) {
this.name = name;
this.priority = priority;
this.arriveTime = arriveTime;
this.serveTime = serveTime;
this.cpuTime = cpuTime;
}
public String toString() {
String info=new String("进程名: "+name+" 进程状态:"+processState+" 优先数:"+ priority
+" 到达时间:"+arriveTime+" 服务时间:"+serveTime+" 已用CPU时间:"+cpuTime );
return info;
}
}
public class processMenu {
public static void main(String[] args) {
process p = new process();
p.init();
while(true) {
System.out.println("请选择要验证的进程调度算法:1.先来先服务(A) 2.短作业优先(B) 3.最高优先数调度(C) 4.多级反馈队列(D)");
Scanner scanner = new Scanner(System.in);
String string = scanner.next();
switch(string) {
case "A":
p.FCFS();
break;
case "B":
p.SJF() ;
break;
case "C":
p.HPF();
break;
case "D":
p.MFQ();
break;
default:
System.out.println("输入错误请重新输入!");
}
}
}
}
class process {
Queue<PCB> P1 = new LinkedList<PCB>();
Queue<PCB> P2 = new LinkedList<PCB>();
Queue<PCB> P3 = new LinkedList<PCB>();
ArrayList<PCB> pcb;// 存放所有进程
LinkedList<PCB> link;// 存放进入就绪队列的进程
ArrayList<PCB> new_jcb;// 存放按指定调度算法结束的进程
PCB nowProess, nextProess;// 当前应执行进程
LinkedList<PCB> t1,t5,t10;
LinkedList [] a = new LinkedList[3];
public void init() {//初始化
pcb = new ArrayList<PCB>();
link = new LinkedList<PCB>();
new_jcb = new ArrayList<PCB>();
t1 = new LinkedList<PCB>();
t5 = new LinkedList<PCB>();
t10 = new LinkedList<PCB>();
a[0] = t1;
a[1] = t5;
a[2] = t10;
PCB p1 = new PCB("进程"+1, 1 , 1 , 2 , 0);
PCB p2 = new PCB("进程"+2, 2 , 2 , 6 , 0) ;
PCB p3 = new PCB("进程"+3, 3 , 4 , 4 , 0) ;
PCB p4 = new PCB("进程"+4, 1 , 6 , 5 , 0) ;
PCB p5 = new PCB("进程"+5, 2 , 8 , 2 , 0) ;
pcb.add(p1);pcb.add(p2);pcb.add(p3);pcb.add(p4);pcb.add(p5);
//先将jcb排序,便于下面的算法实现,就不需要再定义一个标识进程是否已到达的boolean,即无需每次都从头开始扫描jcb容器,
//而是用一个K记录下当前已经扫描到的位置,一次遍历即可,提高了算法效率。
Collections.sort(pcb, new compareAt_St());
}
public void FCFS(){//先来先服务算法
ProcessQueue pq= new ProcessQueue();//调用内部类
pq.EnqueueLast();//让最先到达的进程先入队
System.out.println("先来先服务算法模拟***********************************************");
while(!link.isEmpty()) {//while(new_jcb.size()!=jcb.size())
pq.Dequeue();//出队,一次一个
pq.DisplayQueue();//打印当前队列中的进程
pq.newJcb();
pq.EnqueueLast();//已到达的进程入队
System.out.println();
}
pq.printProcess();
}
public void SJF() {// 短作业优先算法
ProcessQueue pq=new ProcessQueue();
pq.EnqueueLast();
System.out.println("短作业优先算法模拟**********************************************");
while(!link.isEmpty()) {
// pq.MhqEnqueue();
pq.Dequeue();//一个进程从就绪队列到运行队列,
pq.DisplayQueue();//打印当前队列中的进程
pq.newJcb();
pq.EnqueueLast();//已到达的进程入就绪队
Collections.sort(link, new compareSt());//队列中的进程还需按服务时间长度进行排序
}
pq.printProcess();
}
public void MFQ() {//多级反馈调度算法
System.out.println("多级反馈队列调度算法模拟*****************************************************");
ProcessQueue pq=new ProcessQueue();
pq.MhqEnqueue();
while (!pcb.isEmpty()) {
if(!P3.isEmpty()) {
pq.Dequeue(100,P3);//出队,一次一个,因为上一轮出的得让刚到达的进程先进队列,所以没办法,进队操作只能也放在这个函数里了
pq.printQueue();//打印当前队列中的进程
pq.MhqEnqueue();
}
if(!P2.isEmpty()) {
pq.Dequeue(4, P2);//出队,一次一个,因为上一轮出的得让刚到达的进程先进队列,所以没办法,进队操作只能也放在这个函数里了
pq.printQueue();//打印当前队列中的进程
pq.MhqEnqueue();
}
if(!P1.isEmpty()) {
pq.Dequeue(2, P1);//出队,一次一个,因为上一轮出的得让刚到达的进程先进队列,所以没办法,进队操作只能也放在这个函数里了
pq.printQueue();//打印当前队列中的进程
pq.newJcb();
pq.MhqEnqueue();
}
}
pq.printProcess();
}
public void HPF() {//最高优先数优先调度算法
ProcessQueue pq=new ProcessQueue();
pq.EnqueueLast();
System.out.println("最高优先数优先调度算法模拟*************************************************");
while(!link.isEmpty()) {
pq.Dequeue();//一个进程从就绪队列到运行队列,
pq.DisplayQueue();//打印当前队列中的进程
pq.newJcb();
pq.EnqueueLast();//已到达的进程入就绪队
Collections.sort(link, new comparePriority() );//队列中的进程还需按服务时间长度进行排序
}
pq.printProcess();
}
class ProcessQueue{
int k = 0;// jcb中的进程遍历时的下标
int nowTime = pcb.get(0).arriveTime;// 当前时间
int leftTime = 0;
int preTime = 0;
double sliceTime;//轮转调度时间片
int i=0;//记录当前出入队列的次数
public void EnqueueLast() {//进程首次入就绪队列,可一次进多个,从队尾进入
while (k < pcb.size()) {//当遍历完jcb中的所有进程时结束
if (pcb.get(k).arriveTime <= nowTime) {//已经到达的进程按到达时间先后进入队列
link.addLast(pcb.get(k));
k++;
} else {
break;//如果该进程还未入队,即先结束遍历,保留当前下标k值,
}
}
}
int pc = 11;
public void MhqEnqueue() {//进程首次入队,可一次进多个,从队首进入
while (k < pcb.size()) {//当遍历完jcb中的所有进程时结束
if (pcb.get(k).arriveTime <= nowTime) {//已经到达的进程按到达时间先后进入队列
pc = pcb.get(k).priority;
if(pc == 1)
P1.offer(pcb.get(k));
if(pc == 2)
P2.offer(pcb.get(k));
if(pc == 3)
P3.offer(pcb.get(k));
k++;
} else {
break;//如果该进程还未入队,即先结束遍历,保留当前下标k值,;
}
}
}
public int getPC() {
return pc;
}
public void Dequeue() {//进程出队,一次只出一个.就绪队列出一个进程到运行状态。
nowProess = link.removeFirst();//移除队列的队首元素并且返回该对象元素
nowProess.cpuTime = nowProess.serveTime;//计算已用CPU时间
nowProess.processState = "R";
nowProess.beginTime = nowTime;//计算开始时间,即为上一个进程的结束时间
nowProess.finshTime = nowProess.beginTime + nowProess.serveTime;//计算结束时间,该进程开始时间+服务时间
nowProess.roundTime = nowProess.finshTime - nowProess.arriveTime;//计算周转时间
nowProess.aveRoundTime = (double) nowProess.roundTime / nowProess.serveTime;//计算平均周转时间
nowTime = nowProess.finshTime;//获得结束时间,即当前时间,方便判断剩下的进程是否已到达
for(int i=0;i<link.size();++i) {
link.get(i).waitTime += nowProess.serveTime;//所有进入等待队列的进程的等待时间.
}
}
public void newJcb() {
new_jcb.add(nowProess);//经处理过数据后加入new_jcb容器
new_jcb.get(new_jcb.size()-1).processState = "F";
}
public void Dequeue(int sliceTime,Queue<PCB> p) {//重载Dequeue方法,实现轮转调度算法的出队
nowProess = p.poll();//移除队列的队首元素并且返回该对象元素
nowProess.beginTime = nowTime ;//进程开始执行的时间
nowTime+=sliceTime;//每次出队,用时一个时间片,更新当前时间
leftTime = nowProess.serveTime;
if(leftTime <=sliceTime) {
nowProess.cpuTime += leftTime;
nowProess.finshTime = preTime + leftTime;
nowProess.roundTime = nowProess.finshTime - nowProess.arriveTime;//计算周转时间
nowProess.aveRoundTime = (double) nowProess.roundTime / nowProess.serveTime;//计算平均周转时间
new_jcb.add(nowProess);//经处理过数据后加入new_jcb容器
new_jcb.get(new_jcb.size()-1).processState = "F";
MhqEnqueue();//已到达的进程先入队
}if(leftTime > sliceTime) {
nowProess.cpuTime +=sliceTime;//更新当前出队列的进程已服务时间
nowProess.finshTime = nowTime;//计算该进程完成时间
nowProess.processState = "W";
MhqEnqueue();//已到达的进程先入队
// nowProess.priority -= 1;
nowProess.priority -=1;
if(nowProess.priority == 2) {
P2.offer(nowProess);
}
if(nowProess.priority == 0||nowProess.priority == 1) {
P1.offer(nowProess);
}
}
leftTime = nowProess.serveTime - nowProess.cpuTime;
}
public void printQueue(){//每一次调度中就绪队列中等候的进程
i++;
System.out.println("第"+i+"就绪次队列中排队的进程:");
for (PCB pcb : P1) {
System.out.println(pcb);
}
for (PCB pcb : P2) {
System.out.println(pcb);
}
for (PCB pcb : P3) {
System.out.println(pcb);
}
System.out.println("第"+i+"次完成队列中已完成的进程:");
for (int y = 0;y < new_jcb.size() ;y++) {
System.out.println(new_jcb.get(y).toString());
}
System.out.println();
}
public void DisplayQueue(){//每一次调度中就绪队列中等候的进程
i++;
System.out.println("第"+i+"就绪次队列中排队的进程:");
for (PCB pcb : link) {
System.out.println(pcb);
}
System.out.println("第"+i+"次运行队列中正在运行的进程:");
System.out.println(nowProess);
System.out.println("第"+i+"次完成队列中已完成的进程:");
for (int y = 0;y < new_jcb.size() ;y++) {
System.out.println(new_jcb.get(y).toString());
}
System.out.println();
}
public void printProcess() {
System.out.println("进程名 到达时间 服务时间 开始时间 完成时间 周转时间 带权周转时间");
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 compareSt implements Comparator<PCB> {// 按服务时间升序
public int compare(PCB arg0, PCB arg1) {
return arg0.serveTime - arg1.serveTime;
}
}
class compareAt_St implements Comparator<PCB> {// 按到达时间升序,若到达时间相同,按服务时间升序
public int compare(PCB o1, PCB 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 comparePriority implements Comparator<PCB>{//按优先权升序
public int compare(PCB o1, PCB o2) {
return o1.priority - o2.priority;
}
}
进程调度
最新推荐文章于 2022-01-05 18:56:28 发布