进程调度java实现(FCFS,SJF,HRRN,RR)

进程JCB类实现

我们设置了一系列描述进程的参数,并提供一个构造函数用于初始化进程。

public class JCB {
	String name;//进程名
	int arriveTime;//到达时间
	int serveTime;//服务时间
	int beginTime;//开始时间
	int finshTime;//结束时间
	int roundTime;//周转时间
	int waitTime;//等待时间
	double aveRoundTime;//带权周转时间
	double clock=0;//已经服务运行的时间
	boolean firstTimeTag=false;//在RR算法中标识开始时间是否第一次计算
	public JCB() {
		
	}
	public JCB(String name, int arriveTime, int serveTime) {
		super();
		this.name = name;
		this.arriveTime = arriveTime;
		this.serveTime = serveTime;
		this.waitTime = 0;
	}
 
	public String toString() {
		String info=new String("进程名:P"+this.name);
		return info;
	}
	
}

processMenu类的实现

本节我们首先创建三个数组链表,用于存储各个状态的进程JCB

ArrayList<JCB> jcb;// 存放所有进程
LinkedList<JCB> link;// 存放已经进入队列的进程
ArrayList<JCB> new_jcb;// 存放按指定调度算法排序后的进程

对进程初始化,这里我设置了进程的参数,其实顺便设置都行。

public void init() {//初始化
        jcb = new ArrayList<JCB>();
        link = new LinkedList<JCB>();
        new_jcb = new ArrayList<JCB>();
        JCB p1 = new JCB("1", 0, 4);
        JCB p2 = new JCB("2", 1, 3);
        JCB p3 = new JCB("3", 2, 5);
        JCB p4 = new JCB("4", 3, 2);
        JCB p5 = new JCB("5", 4, 4);
        jcb.add(p1);
        jcb.add(p2);
        jcb.add(p3);
        jcb.add(p4);
        jcb.add(p5);
    }

 根据算法实现原理,我们可以知道除了时间片轮转算法RR的进程执行方法不一样之外,其他的FCFS、SJF和HRRN的方法一样,都只是在执行之前根据要求对link里面的JCB进程按照各自的算法进行排序,所以他们共用一个Dequeue方法,对于RR我们通过对Dequeue重写,提供参数(时间片)来控制。

并且在进程的执行过程中我们还需要更新当前时间、其他进程的等待时间、进程的完成时间,还需要计算周转时间等参数。

排序的算法,我们通过Collections的sort方法实现,但是我们需要重写一个类继承sort方法的参数Comparator,实现按照我们需要的算法要求对JCB排序。

对于RR算法,唯一需要注意的是在每次使用完时间片的时候要注意更新时间。

package rjxy.xju;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.Scanner;
 
public class processMenu {
 
	ArrayList<JCB> jcb;// 存放所有进程
	LinkedList<JCB> link;// 存放已经进入队列的进程
	ArrayList<JCB> new_jcb;// 存放按指定调度算法排序后的进程
	JCB nowProess;// 当前应执行进程
 
	public void init() {//初始化
		jcb = new ArrayList<JCB>();
		link = new LinkedList<JCB>();
		new_jcb = new ArrayList<JCB>();
		JCB p1 = new JCB("1", 0, 4);
		JCB p2 = new JCB("2", 1, 3);
		JCB p3 = new JCB("3", 2, 5);
		JCB p4 = new JCB("4", 3, 2);
		JCB p5 = new JCB("5", 4, 4);
		jcb.add(p1);
		jcb.add(p2);
		jcb.add(p3);
		jcb.add(p4);
		jcb.add(p5);
	}
 
	public void FCFS(){//先来先服务算法
		ProcessQueue pq=new ProcessQueue();
		pq.EnqueueLast();//进程入队
		System.out.println("*****************************************************");
		while(!link.isEmpty()) {
			pq.DisplayQueue();//打印当前队列中的进程
			pq.Dequeue();//出队
			pq.EnqueueLast();//进程入队
			Collections.sort(link, new compareAt_St());
		}
	}
	public void SJF() {
		ProcessQueue pq=new ProcessQueue();
		pq.EnqueueLast();
		System.out.println("*****************************************************");
		while(!link.isEmpty()) {
			pq.DisplayQueue();
			pq.Dequeue();
			pq.EnqueueLast();
			Collections.sort(link,new compareSt());
		}
	}
	public void HRRN() {
		ProcessQueue pq=new ProcessQueue();
		pq.EnqueueLast();
		System.out.println("*****************************************************");
		while(!link.isEmpty()) {
			pq.DisplayQueue();
			pq.Dequeue();
			pq.EnqueueLast();
			Collections.sort(link,new compareRt());
		}
	}
	public void RR() {
		ProcessQueue pq=new ProcessQueue();
		pq.EnqueueLast();
		System.out.println("*****************************************************");
		while(!link.isEmpty()) {
			pq.DisplayQueue();//打印当前队列中的进程
			pq.Dequeue(1);//出队
		}	
	}
	class ProcessQueue{
		int k = 0;// jcb中的进程遍历时的下标
		int nowTime = 0;// 当前时间
		int i=0;//记录当前出入队列的次数
		public void EnqueueLast() {
			while (k < jcb.size()) {//遍历jcb
				if (jcb.get(k).arriveTime <= nowTime) {//已经到达的进程按到达时间先后进入队列
					link.addLast(jcb.get(k));
					k++;
				} else {
					break;
				}
			}
		}
		public void EnqueueFirst() {//进程入队
			while (k < jcb.size()) {//遍历jcb
				if (jcb.get(k).arriveTime <= nowTime) {//已经到达的进程按到达时间先后进入队列
					link.addFirst(jcb.get(k));
					k++;
				} else {
					break;//如果该进程还未入队,即先结束遍历,保留当前下标k值,注意:此处不要k--;
				}
			}
		}
		public void Dequeue() {//进程出队,一次只出一个
			nowProess = link.removeFirst();//移除队列的队首元素并且返回该对象元素
			nowProess.beginTime = nowTime;//计算开始时间,即为上一个进程的结束时间
			nowProess.finshTime = nowProess.beginTime + nowProess.serveTime;//计算结束时间,该进程开始时间+服务时间
			nowProess.roundTime = nowProess.finshTime;//计算周转时间
			nowProess.aveRoundTime = (double) nowProess.roundTime / nowProess.serveTime;//计算平均周转时间
			nowTime = nowProess.finshTime;//获得结束时间,即当前时间,方便判断剩下的进程是否已到达
			new_jcb.add(nowProess);//经处理过数据后加入new_jcb容器
			for(int i=0;i<link.size();++i) {
				link.get(i).waitTime++;//所有进入等待队列的进程等待时间+1
			}
		}
		public void Dequeue(double sliceTime) {//重载Dequeue方法,实现轮转调度算法的出队
			nowProess = link.removeFirst();//取出队首元素
			if(nowProess.firstTimeTag==false) {
				nowProess.beginTime=nowTime;//进程开始执行的时间
				nowProess.firstTimeTag=true;//计算第一次即可,下次无需更新计算
			}
			nowTime+=sliceTime;//用掉一个时间片
			nowProess.clock+=sliceTime;//更新clock
			if(nowProess.clock>=nowProess.serveTime) {
				nowProess.finshTime=nowTime;//计算该进程完成时间
				nowProess.roundTime = nowProess.finshTime - nowProess.arriveTime;//计算周转时间
				nowProess.aveRoundTime = (double) nowProess.roundTime / nowProess.serveTime;//计算平均周转时间
				new_jcb.add(nowProess);
				EnqueueFirst();//已到达的进程先入队
			}
			else {
				EnqueueFirst();//已到达的进程先入队
				link.addLast(nowProess);//上一轮出的再紧接着进入队尾
			}
		}
		public void DisplayQueue(){//打印队列中等候的进程
			i++;
			System.out.println("第"+i+"次队列中排队的进程:"+link);
		}
	}
	public void printProcess() {
		System.out.println("进程名\t到达时间\t服务时间\t开始时间\t完成时间\t周转时间\t带权周转时间");
		for (int i = 0; i < new_jcb.size(); ++i) {
			System.out.println("P"+new_jcb.get(i).name + "\t" + new_jcb.get(i).arriveTime + "\t" +
		new_jcb.get(i).serveTime+ "\t" + new_jcb.get(i).beginTime + "\t" + new_jcb.get(i).finshTime +
		"\t"+ new_jcb.get(i).roundTime + "\t" + new_jcb.get(i).aveRoundTime);
		}
		new_jcb.clear();//清空new_jcb
	}
}

class compareAt_St implements Comparator<JCB> {// 按到达时间升序,若到达时间相同,按服务时间升序
	public int compare(JCB o1, JCB o2) {
		int a = o1.arriveTime - o2.arriveTime;
		if (a > 0)
			return 1;
		else if (a == 0) {
			return o1.serveTime > o2.serveTime ? 1 : -1;
		} else
			return -1;
	}
}

class compareSt implements Comparator<JCB>{

	@Override
	public int compare(JCB o1, JCB o2) {
		// TODO 自动生成的方法存根
		return o1.serveTime >= o2.serveTime ? 1 : -1;
	}
	
}
class compareRt implements Comparator<JCB>{

	@Override
	public int compare(JCB o1, JCB o2) {
		// TODO 自动生成的方法存根
		double r1=(double) (o1.waitTime+o1.serveTime)/o1.serveTime;
		double r2=(double) (o2.waitTime+o2.serveTime)/o2.serveTime;
		return r1<r2?1:-1;
	}
	
}

TestProcess类的实现

package rjxy.xju;

public class TestProcess {
	public static void main(String[] args) {
		processMenu pm=new processMenu();
		pm.init();//初始化容器
		pm.FCFS();
		pm.printProcess();
		pm.SJF();
		pm.printProcess();
		pm.HRRN();
		pm.printProcess();
		pm.RR();
		pm.printProcess();
	}
}

算法实现的结果

FCFS算法实现

SJF算法实现

 HRRN算法实现

 RR算法实现

  • 14
    点赞
  • 88
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Java实现进程调度算法,需要先定义一个 Process 类,表示一个进程,包含进程的 PID、优先级、需要执行的时间等属性。然后,可以根据具体的调度算法,实现不同的调度方法。 以下是一个简单的先来先服务(FCFS调度算法的实现: ```java import java.util.*; class Process { int pid; int priority; int arrivalTime; int burstTime; int waitingTime; int turnaroundTime; public Process(int pid, int priority, int arrivalTime, int burstTime) { this.pid = pid; this.priority = priority; this.arrivalTime = arrivalTime; this.burstTime = burstTime; } } public class Scheduler { public static void main(String[] args) { List<Process> processes = new ArrayList<>(); // 添加进程 processes.add(new Process(1, 2, 0, 5)); processes.add(new Process(2, 1, 2, 3)); processes.add(new Process(3, 3, 4, 1)); processes.add(new Process(4, 4, 5, 2)); int currentTime = 0; for (Process p : processes) { p.waitingTime = currentTime - p.arrivalTime; currentTime += p.burstTime; p.turnaroundTime = currentTime - p.arrivalTime; } // 输出结果 System.out.println("PID\tPriority\tArrival Time\tBurst Time\tWaiting Time\tTurnaround Time"); for (Process p : processes) { System.out.println(p.pid + "\t" + p.priority + "\t\t" + p.arrivalTime + "\t\t" + p.burstTime + "\t\t" + p.waitingTime + "\t\t" + p.turnaroundTime); } } } ``` 在上面的代码中,先定义了一个 Process 类,表示一个进程,包含进程的 PID、优先级、到达时间、需要执行时间、等待时间和周转时间等属性。然后,创建了一个包含多个进程的 List 对象,表示调度队列。 接着,使用一个 for 循环对每个进程进行调度,按照 FCFS 调度算法的规则,先到达的进程先执行。在执行进程之前,计算该进程的等待时间和周转时间,并更新当前时间。 最后,输出每个进程的信息,包括 PID、优先级、到达时间、需要执行时间、等待时间和周转时间。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

会掉头发

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值