(1)先来先服务调度算法:调度时,总是选择到达时间最早的进程;
(2)基于优先级的调度算法:调度时,总是选择优先级最高的进程。
程序实现:
public class PCB { //进程控制块
int id; //进程id
int status; //进程状态0就绪,1执行,2结束
int arriveTime; //到达时间
int serviceTime; //估计运行时间
int startTime; //开始执行时间
int pri; //优先级
int time;
public PCB() {}
public PCB(int id, int arriveTime, int serviceTime) { //构造器
this.id = id;
this.status = 0;
this.arriveTime = arriveTime;
this.serviceTime = serviceTime;
}
public PCB(int id, int arriveTime,int serviceTime,int pri) { //构造器,创建带优先级进程
this.id = id;
this.status = 0;
this.arriveTime = arriveTime;
this.serviceTime = serviceTime;
this.pri = pri;
}
public void run() { //运行进程
System.out.println("procss"+this.id+" is running...");
try {
sleep(this.serviceTime*1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("process"+this.id+" is finish.");
}
public int getTime() { //获取进程周转时间(结束时间-到达时间)
this.time = this.startTime+this.serviceTime-this.arriveTime;
System.out.println(this.id+":周转时间为"+this.time);
return this.time;
}
}
public class CPU {
PCB running = null;
Set<PCB> readySet = new HashSet<PCB>(); //就绪集合存放就绪进程
Set<PCB> finishSet = new HashSet<PCB>(); //存放完结进程的集合
Queue<PCB> readyQueue = new LinkedList<PCB>(); //就绪队列,cpu依此调度进程
Set<PCB> tasks = new HashSet<PCB>(); //任务池,存放所有未进入就绪队列的进程
int nowtime = 0;
public PCB createProcess(int id) { //创建进程
int arriveTime;
int serverTime;
Scanner sc = new Scanner(System.in);
System.out.println("进程"+id+":请输入(进程到达时间,进程需要服务时间):");
arriveTime = sc.nextInt();
serverTime = sc.nextInt();
PCB pcb = new PCB(id,arriveTime,serverTime);
tasks.add(pcb);
return pcb;
}
public PCB createProcessWithPri(int id) { //带优先级创建进程
int arriveTime;
int serverTime;
int pri;
Scanner sc = new Scanner(System.in);
System.out.println("进程"+id+":请输入进程(到达时间,需要服务时间,进程优先级):");
arriveTime = sc.nextInt();
serverTime = sc.nextInt();
pri = sc.nextInt();
PCB pcb = new PCB(id,arriveTime,serverTime,pri);
tasks.add(pcb);
return pcb;
}
public PCB getFirst(int min) { //获得任务池中到达时间小于当前时间的最早的一个进程。
PCB pcb = null;
for(PCB task:this.tasks) { //获取任务池中的最早到达时间
if(min==0) {
min = task.arriveTime;
pcb = task;
continue;
}
if(task.arriveTime<min) {
min = task.arriveTime;
pcb = task;
}
}
return pcb;
}
public void refreshReady(boolean flag) { //更新就绪列表,flag为false表示当前时间没有进程在就绪队列
PCB pcb = null; //flag为true时表示当前时间就绪队列中仍有未执行的进程
if(flag) {
do{
pcb = this.getFirst(nowtime);
if(pcb!=null) {
readyQueue.add(pcb);
readySet.add(pcb);
tasks.remove(pcb);
}
}while(pcb!=null); //直到当前时间没有进程到达
}
else { //获取一个最早到达的进程,将当前时间设置为该进程到达时间
pcb = this.getFirst(0);
readySet.add(pcb);
readyQueue.add(pcb);
tasks.remove(pcb);
nowtime = pcb.arriveTime;
}
}
public void refreshReadyWithPri(boolean flag) {//更新就绪列表,flag为false表示当前时间没有进程 PCB pcb = null; //在就绪队列,true表示当前时间就绪队列中仍有未执行进程
int pri = 0;
Set<PCB> rset = new HashSet<PCB>();
if(flag) {
do{
pcb = this.getFirstWithPri(nowtime);
if(pcb!=null) {
readySet.add(pcb);
tasks.remove(pcb);
}
}while(pcb!=null); //直到当前时间没有进程到达
rset.addAll(readySet); //就绪集合中的所有进程添加到rset中
readyQueue.clear(); //清空就绪队列
while(!rset.isEmpty()) { //将rset中的所有进程按优先级排序,依次添加到就
for(PCB item:rset) { //绪队列
if(pri<item.pri) {
pcb = item;
pri = item.pri;
}
}
rset.remove(pcb);
pri=0;
readyQueue.add(pcb);
}
}
else { //获取一个最早到达的进程,将当前时间设置为该进程到达时间
pcb = this.getFirst(0);
nowtime = pcb.arriveTime;
refreshReadyWithPri(true);
}
}
public void start(int method){ //调度函数,method为0位先来先服务,为1则为优先级调度
PCB pcb;
while(!tasks.isEmpty()) {
if(readyQueue.isEmpty()&&!tasks.isEmpty()) {
if(method==0)
refreshReady(false);
if(method==1)
refreshReadyWithPri(false);
}
while(!readyQueue.isEmpty()) {
pcb = readyQueue.poll();
readySet.remove(pcb);
pcb.status = 1;
pcb.startTime = nowtime;
pcb.run();
nowtime += pcb.serviceTime;
System.out.println("当前运行的进程:");
System.out.println("pid\t status\t arrivaTime\t serverTime\t starTime");
System.out.println(pcb.id+"\t "+pcb.status+"\t "+pcb.arriveTime+"\t\t "+pcb.serviceTime+"\t\t"+pcb.startTime);
pcb.status = 2;
finishSet.add(pcb);
if(method==0)
refreshReady(true);
if(method==1)
refreshReadyWithPri(true);
showReady();
}
}
}
public void showReady() { //打印就绪队列
System.out.println("就绪队列的进程:");
System.out.println("pid\t status\t arrivaTime\t serverTime\t");
for(PCB pcb:readySet) {
System.out.println(pcb.id+"\t"+pcb.status+"\t"+pcb.arriveTime+"\t\t"+pcb.serviceTime+"\t");
}
}
public void showAvTime() { //打印每个进程的周转时间和平均周转时间。
float sum=0,avTime;
int count=0,time;
for(PCB pcb:finishSet) {
time = pcb.getTime();
sum+=time;
count++;
}
avTime = sum/count;
System.out.println("平均周转时间:"+avTime);
}
public static void main(String[] args) {
CPU cpu = new CPU();
int method = 1;
PCB pcb = null;
for(int i=1; i<6; i++) {
if(method==0)
pcb = cpu.createProcess(i);
else
pcb = cpu.createProcessWithPri(i);
}
cpu.start(1);
System.out.println("finish");
}
}