import java.util.*;
/**
* @author yikangchen
* 学习内容:写的是抢占式短作业优先
*/
class Job{
String name;
int arrive;
int service;
String status;//状态
int surplus;//剩余服务时间
public Job() {
}
public Job(String name, int arrive, int service, String status) {
this.name = name;
this.arrive = arrive;
this.service = service;
this.status = status;
this.surplus = service;
}
@Override
public String toString() {
return "Job{" +
"name='" + name + '\'' +
", arrive=" + arrive +
", service=" + service +
", status='" + status + '\'' +
", surplus=" + surplus +
'}';
}
}
/**
* 还有一些细枝末节:只有一个进程处于运行,切换时,队列中其余的进程状态切为wait,Finish的直接出队,这点没有实现
* 给服务时间设个全局变量?
* 最后计算一下带权周转时间
*/
public class test {
PriorityQueue<Job> deque = new PriorityQueue<>((Comparator.comparingInt(o -> o.surplus)));
//这点是按剩余服务时间来排,而不是按服务时间,只有刚来时服务时间等于剩余服务时间
public void SJF(Job[] jobs){
int mark = 0;
Arrays.sort(jobs, (Comparator.comparingInt(o -> o.arrive)));//先将作业按到达时间进行排序
for(int time = 0;time < 100;time++){//由于只是简单实现time随意设计了一下
if(time == jobs[mark].arrive) {
deque.add(jobs[mark]);
mark++;
if(mark == jobs.length){
mark--;
}
}
if(!deque.isEmpty()){
Job run = deque.peek();//每次队首是已到的里面服务时间最短的
if(run.status == "W"){
run.status = "R";
}
run.surplus--;
if(run.surplus == 0) {
run.status = "F";
System.out.println(run);
int turnover_time = time - run.arrive + 1;
System.out.println("作业完成时间:" + (time + 1) + "\t"+ "周转时间:" + turnover_time + "\t" +
"带权周转时间" + (double)turnover_time/run.service );
/*+1的原因找到了:因为开始服务,剩余时间就开减,后面time++,最后一次减了,这时候就打印了,time没来得及加
所以相当于是time + 1 - run.arrive*/
deque.remove();
}
}
}
}
public static void main(String[] args) {
Job a = new Job("a", 0, 5, "W");
Job b = new Job("b", 1, 3, "W");
Job c = new Job("c", 3, 2, "W");
Job d = new Job("d", 6, 1, "W");
Job[] jobs = new Job[]{a,b,c,d};
test test = new test();
test.SJF(jobs);
}
}
以时间为驱动,作业来时,以作业的服务时间为权进入优先级队列,随着时间推进,拿队首元素即可,最终将所有作业执行完即可。
PS:一些细枝末节:只有一个进程处于运行,切换时,队列中其余的进程状态切为wait,Finish的直接出队,意义不大,这点没有实现