import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
/**
* 进程管理对象的实现类
*/
public class FCFS {
/**使用链表存储进程对象,进程队列*/
private static List<Job> jobList=new ArrayList<Job>();
/**系统处理进程的总耗时*/
private static float time;
/**平均周转时间*/
private static float avTurnTime;
/**平均等待时间*/
private static float avWaitTime;
/**平均带权周转时间*/
private static float avWeightTime;
//主函数
public static void main(String[] args) {
initialList();
input();
List<Job> list=FSFC();
//输出进程信息。
for(Job job:list){
System.out.println("进程名:"+job.getJobName()+
",到达时间:"+job.getReachTime()+
",运行时间:"+job.getServeTime()+
",开始执行时间:" + job.getStartTime()+
",完成时间:"+job.getRunTime()+
",周转时间:"+job.getTurnTime()+
",带权周转时时间:"+job.getAvTuTime()+
",等待时间:"+job.getWaitTime());
}
calculateTheAverage(list);
System.out.println("处理总时间为:"+time+
",平均周转时间: "+avTurnTime+
",平均带权周转时间:"+avWeightTime+
",平均等待时间: "+avWaitTime);
}
/**
* 初始化链表
*/
public static void initialList(){
System.out.println("请输入要处理的作业数");
Scanner in=new Scanner(System.in);
int length=in.nextInt();
for (int i = 0; i < length; i++) {
jobList.add(new Job());
}
}
/**
* 输入作业名和到达时间和服务时间
*/
public static void input() {
for (int i = 0; i < jobList.size(); i++) {
Job job=jobList.get(i);
System.out.println("请输入第"+(i+1)+"个作业名");
Scanner in=new Scanner(System.in);
job.setJobName(in.next());
System.out.println("请输入第"+(i+1)+"个作业的到达时间");
job.setReachTime(in.nextFloat());
System.out.println("请输入第"+(i+1)+"个作业的服务时间");
job.setServeTime(in.nextFloat());
}
}
/**
* 发现集合中的最小值,并返回其对应的下标
* @return
*/
public static int findMin(){
//获得第一个进程的到达时间
float min=jobList.get(0).getReachTime();
for (int i = 0; i < jobList.size(); i++) {
if(min>jobList.get(i).getReachTime()){
min=jobList.get(i).getReachTime();
}
}
for (int i = 0; i < jobList.size(); i++) {
if(min==jobList.get(i).getReachTime()){
return i;
}
}
return -1;
}
/**
* 作业处理
* @return
*/
public static List<Job> FSFC(){
List<Job> resultQueue=new ArrayList<>();//完成队列
int index=0;
while(jobList.size()!=0){
//发现集合中的进程到达时间最小的下标
index=findMin();
//判断进程处理总时间是否为空,为空说明PCB刚刚开始
//获得对应下标的对象
Job job=jobList.get(index);
//系统开始位第一个进程服务
if(time==0){
//第一个进程,开始执行时间=进程到达时间
//计算开始执行时间
job.setStartTime(job.getReachTime());
//完成时间=开始执行时间+服务时间
job.setRunTime(job.getStartTime()+job.getServeTime());
//周转时间=完成时间-到达时间
job.setTurnTime(job.getRunTime()-job.getReachTime());
//带权周转时间=周转时间/运行时间(服务时间)
job.setAvTuTime((job.getTurnTime()/job.getServeTime()));
//等待时间=周转时间-运行时间
job.setWaitTime(job.getTurnTime()-job.getServeTime());
//此时系统时间=该进程的完成时间
time=job.getRunTime();
}else {
//如果前一个完成时间,小于到达时间,系统有空闲
if(time<job.getReachTime()){
//空闲出来的时间
float idle=job.getReachTime()-time;
time+=idle;
}
//排除第一个进程 开始执行时间=系统时间
job.setStartTime(time);
//完成时间=开始执行时间+服务时间(运行时间)
job.setRunTime(job.getStartTime()+job.getServeTime());
//周转时间=完成时间-到达时间
job.setTurnTime(job.getRunTime()-job.getReachTime());
//带权周转时间=周转时间/运行时间(服务时间)
job.setAvTuTime(job.getTurnTime()/ job.getServeTime());
//等待时间=周转时间-运行时间
job.setWaitTime(job.getTurnTime()-job.getServeTime());
//修正系统时间 此时系统时间=原来系统时间+此进程的完成时间(服务时间)
time+=job.getServeTime();
}
//将处理完成的进程添加到完成队列中
resultQueue.add(job);
//将此进程移除原先队列
jobList.remove(index);
}
return resultQueue;
}
/**
* 根据传入的集合
* 计算平均周转时间、平均带权周转时间、平均等待时间
*/
public static void calculateTheAverage(List<Job> jobList ){
//总周转时间
float turnAroundTime=0;
//总带权周转时间
float weighTurnAroundTime=0;
//总等待时间
float waitingTime=0;
for(Job job:jobList){
turnAroundTime+=job.getTurnTime();
weighTurnAroundTime+=job.getAvTuTime();
waitingTime+=job.getWaitTime();
}
//计算平均值
avTurnTime=turnAroundTime/jobList.size();
avWaitTime=waitingTime/jobList.size();
avWeightTime=weighTurnAroundTime/jobList.size();
}
}