思路
根据“在进程获得一次CPU后就将其优先数减少1”来确定进程的优先级的。
整个算法的思路是这样的:
数据结构:
开始时有一个processlist数组保存着5个进程,这5个进程都有各自的name,优先级priority,到达时间arrivalTime,需要运行时间needRunTime,已使用cpu时间usedCPUTime和当前进程状态state。
具体细节:
开始时初始化5个进程,并分别给他们设置初始的属性,然后加入processlist中保存,准备一个readyqueue就绪队列,用于存放arrivalTime==当前时间的但由于优先级问题无法运行的进程。
然后循环遍历"processlist"中的所有进程,如果某个进程的到达时间与当前时间相等,则将其添加到"readyQueue"中,并从"processList"中移除该进程
然后检查当前进程是否执行完毕:如果当前有正在执行的进程(currentProcess不为null),则将其CPU时间加1,并将优先级-1,然后检查其CPU时间是否等于总CPU时间,如果是,则将该进程状态设置为"FINISH"并将currentProcess置为null,从readyqueue移除该进程
检查就绪队列中是否有进程并且此时的current为null:找优先级最大的,运行它。如果"readyQueue"不为空,那么从"readyQueue"中选择优先级最高的进程作为当前执行的进程(currentProcess),并将其从"readyQueue"中移除,同时将其状态设置为"RUNNING"。若当前current不是null即当前有进程running时,则应该在readyqueue中尝试寻找优先级大的进程,并将其作为running进程
每一次循环让time++,模拟系统中时间片的增长
若所有进程都已经finish,则进程调用系统退出,即循环退出。
代码
package test;
/**
* @Author:xsr
* @name:PCB
* @Date:2023/4/21 19:58
* @Filename:PCB
*/
public class PCB {
String processName;//进程名字
int priority;//优先级
int arrivalTime;//到达时间
int needRunTime;//需要运行时间
int usedCPUTime;//已用cpu时间
PCBstate state;//状态
public PCB(String processName, int priority, int arrivalTime,
int needRunTime, int usedCPUTime, PCBstate state) {
this.processName = processName;
this.priority = priority;
this.arrivalTime = arrivalTime;
this.needRunTime = needRunTime;
this.usedCPUTime = usedCPUTime;
this.state = state;
}
public int getUsedCPUTime() {
return usedCPUTime;
}
public void setUsedCPUTime(int usedCPUTime) {
this.usedCPUTime = usedCPUTime;
}
public String getProcessName() {
return processName;
}
public void setProcessName(String processName) {
this.processName = processName;
}
public int getPriority() {
return priority;
}
public void setPriority(int priority) {
this.priority = priority;
}
public int getArrivalTime() {
return arrivalTime;
}
public void setArrivalTime(int arrivalTime) {
this.arrivalTime = arrivalTime;
}
public int getNeedRunTime() {
return needRunTime;
}
public void setNeedRunTime(int needRunTime) {
this.needRunTime = needRunTime;
}
public PCBstate getState() {
return state;
}
public void setState(PCBstate state) {
this.state = state;
}
}
package test;
/**
* @Author:xsr
* @name:PCBstate
* 枚举类
* @Date:2023/4/21 19:59
* @Filename:PCBstate
*/
public enum PCBstate {
RUNNING,
WAIT,
FINISH,
}
package test;
import java.util.ArrayList;
import static test.PCBstate.*;
/**
* @Author:xsr
* 进程调度类
* @name:Scheduler
* @Date:2023/4/21 20:03
* @Filename:Scheduler
*/
public class Scheduler {
public static void main(String[] args) {
ArrayList<PCB> processList = new ArrayList<>();
boolean flag=false;
processList.add(new PCB("A进程",3,0,4,0,WAIT));
processList.add(new PCB("B进程",1,1,4,0,WAIT));
processList.add(new PCB("C进程",4,2,4,0,WAIT));
processList.add(new PCB("D进程",5,3,4,0,WAIT));
processList.add(new PCB("E进程",2,4,4,0,WAIT));
int time=0;//时间线
PCB currentProcess = null;//当前运行进程
ArrayList<PCB> readyQueue = new ArrayList<>();//就绪队列
// readyQueue.add(processList.get(0));
while (!flag){
// 循环遍历"processList"中的所有进程,如果某个进程的到达时间与当前时间相等,
// 则将其添加到"readyQueue"中,并从"processList"中移除该进程
if(!processList.isEmpty()){
for(int i=0;i<processList.size();i++){
PCB p = processList.get(i);
if(p.getArrivalTime()==time){
readyQueue.add(p);
processList.remove(0);
i--;
}
}
}
// 检查当前进程是否执行完毕:如果当前有正在执行的进程(currentProcess不为null),
// 则将其CPU时间加1,然后检查其CPU时间是否等于总CPU时间,如果是,则将该进程状态设置为"FINISHED"并将currentProcess置为null
// 并将优先级-1
if (currentProcess != null) {
currentProcess.setUsedCPUTime(currentProcess.getUsedCPUTime()+1);
currentProcess.setPriority(currentProcess.getPriority()-1);
if (currentProcess.getUsedCPUTime() == currentProcess.getNeedRunTime()) {
currentProcess.setState(FINISH);
readyQueue.remove(currentProcess);
currentProcess = null;
}
}
// 检查就绪队列中是否有进程并且此时current为null:找优先级最大的,运行它
// 如果"readyQueue"不为空,
// 那么从"readyQueue"中选择优先级最高的进程作为当前执行的进程(currentProcess),并将其从"readyQueue"中移除,同时将其状态设置为"RUNNING"
if (!readyQueue.isEmpty()&¤tProcess==null) {
currentProcess = readyQueue.get(0);
for (int i = 0; i < readyQueue.size(); i++) {
PCB p = readyQueue.get(i);
if (p.getPriority() > currentProcess.getPriority()) {
currentProcess = p;
}
}
// readyQueue.remove(currentProcess);
currentProcess.setState(RUNNING);
}
//current有,但就绪队列不为空,说明此时需判断队列中是否有比current的优先级大的进程
// 若有则,抢占cpu
else if(!readyQueue.isEmpty()){
for(int i=0;i<readyQueue.size();i++){
PCB pcb = readyQueue.get(i);
if(pcb.getPriority()>currentProcess.getPriority()){
currentProcess=pcb;
}
}
}
// 打印当前状态:输出当前时间、正在执行的进程、就绪队列中的进程以及"processList"中的进程的状态信息
System.out.println("Time: " + time);
System.out.println("Running process: " + (currentProcess == null ? "none" : currentProcess.getProcessName()));
System.out.print("Ready queue: "+(readyQueue.size()==0?"none":"exist "));
for (PCB p : readyQueue) {
System.out.print(p.getProcessName() + "(" + p.getUsedCPUTime() + "), ");
}
System.out.println();
for (PCB p : processList) {
System.out.println(p);
}
System.out.println();
// Increase time
time++;
// 由于这里样本的特殊性,A进程在time=0时就进了readyqueue,
// 因此我这里直接这样判断循环结束条件 了
if(readyQueue.isEmpty()){
flag=true;
}
}
}
}