这是我的作业,要求的输出结果是:各进程的等待时间、周转时间及平均等待、周转时间
个人觉得比较复杂的地方是要考虑进程完成运行时的不同情况:用了多少次时间片、完成运行时时间片有无剩余等,这些都对计算有影响。我用的是分情况考虑来计算的方法,虽然最终能得出结果,但感觉有点繁琐。希望各位大神如果有更简洁的方法,可以指导一下~~~
Work Class:
/*
* Student name: Xin
* Program name: Work
* Program purpose: Test the scheduling algorithm simulation (Round Robin)
*/
import java.util.*;
public class Work {
// 变量
private int arrivalTime;
private int burstTime;
private String name;
// 平均等待、周转时间
private int turnAroundTime;
private int waitingTime;
// 进程还需要时间(运行时间-已使用时间)
private int restRequireTime;
// 进程已使用时间
private int usedTime;
// 获取变量值
public int getArrivalTime() {return arrivalTime;}
public int getBurstTime() {return burstTime;}
public String getName() {return name;}
public int getWaitingTime() {return waitingTime;}
public int getTurnAroundTime() {return turnAroundTime;}
public int getRestRequireTime() {return restRequireTime;}
public int getUsedTime() {return usedTime;}
// 设置变量值
public void setArrivalTime(int arrivalTime) {this.arrivalTime = arrivalTime;}
public void setBurstTime(int burstTime) {this.burstTime = burstTime;}
public void setName(String name) {this.name = name;}
public void setWaitingTime(int waitingTime) {this.waitingTime = waitingTime;}
public void setTurnAroundTime(int turnAroundTime) {this.turnAroundTime = turnAroundTime;}
public void setRestRequireTime(int restRequireTime) {this.restRequireTime = restRequireTime;}
public void setUsedTime(int usedTime) {this.usedTime = usedTime;}
// 第一组数据(进程同时到达)
public static Queue<Work> generateProcess1(){
String[] name1 = {"A","B","C","D","E"};
int[] at1 = {0,0,0,0,0};
int[] bt1 = {7,3,9,5,1};
Queue<Work> runQueue1= new LinkedList<>();
for(int i = 0; i<5;i++){
Work process = new Work();
process.setName(name1[i]);
process.setArrivalTime(at1[i]);
process.setBurstTime(bt1[i]);
runQueue1.add(process);
}
return runQueue1;
}
// 第二组数据(到达时间不同)
public static Queue<Work> generateProcess2(){
String[] name2 = {"A","B","C","D","E"};
int[] at2 = {0,2,4,6,8};
int[] bt2 = {7,3,9,5,1};
Queue<Work> runQueue2= new LinkedList<>();
for(int i = 0; i<5;i++){
Work process = new Work();
process.setName(name2[i]);
process.setArrivalTime(at2[i]);
process.setBurstTime(bt2[i]);
runQueue2.add(process);
}
return runQueue2;
}
}
Test Class:
/*
* Student name: Xin
* Program name: Test
* Program purpose: Test the scheduling algorithm sumulation (Round Robin)
*/
import java.util.*;
/*
* 思路:因为每个进程轮流运行,所以不需事先对进程进行排序(不像SJF和PriorityFirst)。因为有不同的队列,当要选择下一个运行的程序,需要考虑一下情况:(1)准备队列为空;(2)等待队列为空,但原始队列不为空(即有程序很晚才到,别的程序都运行完了它才到达);(3)等待队列不为空
*/
public class Test {
public static int numberOfProcess;
public static int timeQuantum;
// Main method
public static void main(String[] args) {
// 创建Queue
Queue<Work> q1 = new LinkedList<>();
Queue<Work> q2 = new LinkedList<>();
// Call the generateProcess method
q1 = Work.generateProcess1();
q2 = Work.generateProcess2();
System.out.println("--------------------------------------------------");
System.out.println("The running order and details of data set 1: ");
System.out.println("--------------------------------------------------");
roundRobin(q1);
System.out.println("--------------------------------------------------");
System.out.println("The running order and details of data set 2: ");
System.out.println("--------------------------------------------------");
roundRobin(q2);
}
public static Queue<Work> roundRobin(Queue<Work> queue)
{
// 设置变量
double averageWaitTime = 0.00;
double averageTurnAroundTime = 0.00;
int startTime = 0;
int finishTime = 0;
int queueSize = queue.size();
Work process;
// 用户输入时间片大小
Scanner userInputTime = new Scanner(System.in);
System.out.println("Enter the time Quantum");
timeQuantum = userInputTime.nextInt();
// 创建准备队列,等待队列
Queue<Work> waitQueue = new LinkedList<>();
Queue<Work> readyQueue = new LinkedList<>();
// 当所有队列都不为空
while(!queue.isEmpty() || !readyQueue.isEmpty() || !waitQueue.isEmpty()){
// 如果原始队列不为空,且第一个进程的到达时间小于准备队列里的进程的结束时间(即意味着当准备队列里的进程完成运行,下一个进程已经到达),则可以将队列里的进程加入到准备队列里
while(queue.peek()!=null && queue.peek().getArrivalTime()<=finishTime)
readyQueue.add(queue.poll());
// 如果准备队列不为空,则运行准备队列里的进程
if (!readyQueue.isEmpty())
process = readyQueue.poll();
// 如果等待队列为空,而原始队列不为空,则运行原始队列中的进程
else if( !queue.isEmpty() && waitQueue.isEmpty())
process = queue.poll();
else
// If the waitQueue is not empty, run the process in waitQueue
process = waitQueue.poll();
// 计算开始时间和结束时间
startTime = Math.max(process.getArrivalTime(),finishTime);
finishTime = startTime + timeQuantum;
// 计算进程已使用时间和剩余需要时间
process.setUsedTime(process.getUsedTime()+timeQuantum);
process.setRestRequireTime(process.getBurstTime()-process.getUsedTime());
// 如果进程用完时间片仍未完成运行,则返回等待队列
if(process.getRestRequireTime()>0)
{
waitQueue.add(process);}
// If the process finished processing
else
{
// 计算等待时间和总等待时间
// Consider two situations: (1)the process has remain time when it finished; (2)No remain time
if(process.getRestRequireTime()>0)
{
process.setTurnAroundTime(finishTime-process.getArrivalTime());}
else
{
// 如果进程没有用完时间片,则重新计算结束时间
process.setTurnAroundTime(finishTime-process.getArrivalTime()+process.getRestRequireTime());
finishTime = finishTime+process.getRestRequireTime();}
averageTurnAroundTime += process.getTurnAroundTime();
// 计算等待时间,周转时间
// 有两种情况:
// (1)进程只用了一时间片
// (2)进程用了不止一个时间片
if(process.getUsedTime()>timeQuantum)
{
process.setWaitingTime(startTime-process.getUsedTime()+timeQuantum - process.getArrivalTime());}
else
{
process.setWaitingTime(startTime-process.getArrivalTime());}
averageWaitTime += process.getWaitingTime();
// 输出计算结果
System.out.println("\n"+process.getName()+" process finishes processing now. Details are shown: ");
System.out.println("Total waiting time: "+ process.getWaitingTime());
System.out.println("Total turn around time: "+process.getTurnAroundTime());
}
}
// 计算平均值
averageTurnAroundTime /= queueSize;
averageWaitTime /= queueSize;
// Print out the avgs
System.out.println("\nAverage Wait time: "+ averageWaitTime);
System.out.println("Average Turn Around time: "+ averageTurnAroundTime);
return readyQueue;
}
}
运行结果: