Time类
package RR算法;
public class time {
private int hour;
private int min;
public int getHour() {
return hour;
}
public void setHour(int hour) {
this.hour = hour;
}
public int getMin() {
return min;
}
public void setMin(int min) {
this.min = min;
}
public void initTime(String t){
this.hour = Integer.parseInt(t.split(":")[0]);
this.min = Integer.parseInt(t.split(":")[1]);
}
public static int sub(String s,String f){
return Integer.parseInt(f.split(":")[0])*60+Integer.parseInt(f.split(":")[1])
-Integer.parseInt(s.split(":")[0])*60-Integer.parseInt(s.split(":")[1]);
}
@Override
public String toString() {
if(min < 10){
return hour+":0"+min;
}else{
return hour+":"+min;
}
}
}
Process类
package RR算法;
import RR算法.Process;
import RR算法.time;
class jxQueue {
//链结点
Process front;
Process rear;
// public jxQueue() {}
}
public class Process implements Comparable{
private int id; //编号
private String name; // 进程名
int good; //优先级
private time arrive; //到达就绪队列的时间
private int zx; //执行时间
private time firstStart; //进入CPU运行开始的时间
private time finish; //完成时间
private int zz; //周转时间 = 完成时间 - 到达就绪时间
private float zzxs; // 带权周转系数 = 周转时间/执行时间
public Process next;
private int size;
public int flag; //记录该进程的执行次数 flag的最大值等于 执行时间/时间片时间 取整
public int haveFinish; //记录该进程的已完成时间
private time currentStart; //当前开始时间
//初始化操作
public void init(jxQueue q){
this.size =0;
q.front = q.rear = null;
}
//判队空
public boolean isEmpty(jxQueue q) {
if((q.front == q.rear) && size == 0) {
return true;
}else {
return false;
}
}
//入队
public void add(jxQueue q,Process p) {
p.next = null;
if(isEmpty(q)) {
q.front = p;
q.rear = p;
size++;
}else {
q.rear.next = p;
q.rear = p;
size++;
}
}
//出队
public void pop(jxQueue q) {
Process p = q.front;
q.front = p.next;
size--;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getGood() {
return good;
}
public void setGood(int good) {
this.good = good;
}
public time getArrive() {
return arrive;
}
public void setArrive(time arrive) {
this.arrive = arrive;
}
public int getZx() {
return zx;
}
public void setZx(int zx) {
this.zx = zx;
}
public time getfirstStart() {
return firstStart;
}
public void setfirstStart(time firstStart) {
this.firstStart = firstStart;
}
public time getcurrentStart() {
return currentStart;
}
public void setcurrentStart(time currentStart) {
this.currentStart = currentStart;
}
public time getFinish() {
return finish;
}
public void setFinish(time finish) {
this.finish = finish;
}
public int getZz() {
return zz;
}
public void setZz(int zz) {
this.zz = zz;
}
public float getZzxs() {
return zzxs;
}
public void setZzxs(float zzxs) {
this.zzxs = zzxs;
}
@Override
public int compareTo(Object o) {
if( o instanceof Process){
Process t = (Process) o;
return (this.arrive.getHour()*60+this.arrive.getMin())-(t.arrive.getHour()*60+t.arrive.getMin());
}
return 0;
}
@Override
public String toString() {
return "Process{" +
"id=" + id +
", name='" + name + '\'' +
", good=" + good +
", arrive=" + arrive +
", zx=" + zx +
", start=" + firstStart +
", finish=" + finish +
", zz=" + zz +
", zzxs=" + zzxs +
'}';
}
}
Main主函数
package RR算法;
import java.util.ArrayList;
import java.util.Scanner;
import RR算法.Process;
public class Main {
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
System.out.print("请输入操作(1:开始进程调度 0:结束进程):");
int flag = s.nextInt();
while (flag == 1){
ArrayList<Process> list = new ArrayList<>();
ArrayList<Process> list1 = new ArrayList<>(); //用来存放remove了的进程
ArrayList<Process> list2 = new ArrayList<>(); //用来临时存放队首进程
int zz;
int hour=0;
int min=0;
int n = 1; //第n轮执行
System.out.print("请输入时间片时间:");
int para = s.nextInt();
System.out.print("请输入进程数:");
int num = s.nextInt();
System.out.println("请输入进程的参数:");
System.out.println("ID号 名字 优先级 到达时间 执行时间(分钟):");//输入用空格分隔
for (int i = 0; i < num; i++) {
Process p = new Process();
p.setId(s.nextInt());
p.setName(s.next());
p.setGood(s.nextInt());
time t = new time();
t.initTime(s.next());
p.setArrive(t);
p.setZx(s.nextInt());
time tt = new time();
tt.setHour(hour);
tt.setMin(min);
p.setcurrentStart(tt);
p.haveFinish = 0;
p.flag = 0; //初始化执行次数
list.add(p);
}
list.sort(Process::compareTo); //对list的进程按到达时间排序
System.out.println(" ");
jxQueue q = new jxQueue();
Process p = new Process();
p.init(q);
int loc=0;
float sumZz = 0;
float sumZzxs = 0;
// 找出最先到达的进程
for (int i = 1; i < list.size(); i++) {
if(time.sub(list.get(loc).getArrive().toString(),list.get(i).getArrive().toString()) < 0){
loc = i;
}
}
list.get(loc).setcurrentStart(list.get(loc).getArrive());
p.add(q, list.get(loc)); //入就绪队列
list.remove(loc);
while(list.size() != 0 || !p.isEmpty(q)){
int turnFinish = 0; //执行该进程花的时间
if(q.front.getZx()-q.front.flag*para >= para) {
q.front.flag++;
//该进程开始执行,设置首次开始时间
if(q.front.flag==1) {
q.front.setfirstStart(q.front.getcurrentStart());
}
q.front.haveFinish = q.front.flag*para;
turnFinish = para;
}else if(q.front.getZx()-q.front.flag*para < para){
q.front.haveFinish = q.front.getZx();
turnFinish = q.front.getZx() - q.front.flag*para;
}
for(int i=0;i<list.size();i++) {
//如果该次该进程执行完成时已经有新的进程到达,则入队
if(q.front.getcurrentStart().getHour()*60+q.front.getcurrentStart().getMin() + turnFinish >=
list.get(i).getArrive().getHour()*60+list.get(i).getArrive().getMin()) {
p.add(q, list.get(i));
list.remove(i);
i--;
}
}
//如果进程的已完成时间等于总执行时间,进程执行结束,设置完成时间
if(q.front.haveFinish == q.front.getZx()) {
if(q.front.getcurrentStart().getMin()+turnFinish < 60) {
time t1 = new time();
t1.setHour(q.front.getcurrentStart().getHour());
t1.setMin(q.front.getcurrentStart().getMin()+turnFinish);
q.front.setFinish(t1);
}else {
time t2 = new time();
t2.setHour(q.front.getcurrentStart().getHour()+1);
t2.setMin(q.front.getcurrentStart().getMin()+turnFinish-60);
q.front.setFinish(t2);
}
}
// 计算周转时间和周转系数
if(q.front.getFinish() != null) {
zz = time.sub(q.front.getArrive().getHour()+":"+q.front.getArrive().getMin(),
q.front.getFinish().getHour()+":"+q.front.getFinish().getMin());
q.front.setZz(zz);
q.front.setZzxs((float)q.front.getZz()/q.front.getZx());
sumZz += q.front.getZz();
sumZzxs += q.front.getZzxs();
}
System.out.println("第" + n + "轮执行和就绪队列的结果:");
System.out.println("ID号 名字 到达时间 总执行时间(分钟) 当前开始时间 已完成时间(分钟) 剩余完成时间(分钟)");
Process p1 = q.front;
while(p1 != null) {
if(p1 != q.front) {
time t = new time();
t.setHour(0);
t.setMin(0);
p1.setcurrentStart(t);
}
System.out.println(String.format("%-6d",p1.getId())
+String.format("%-6s",p1.getName())
+String.format("%-10s",p1.getArrive().toString())
+String.format("%-13s",p1.getZx()+"(分钟)")
+String.format("%-9s",p1.getcurrentStart().toString())
+String.format("%-10d",p1.haveFinish)
+String.format("%-10d",p1.getZx()-p1.haveFinish));
p1 = p1.next;
}
System.out.println(); //换行
n++; //开始下一轮
//设置下一个进程的当前开始时间 等于前一个进程的当前开始时间加上执行所花费的时间turnFinish
if(q.front.next != null) {
if(q.front.getcurrentStart().getMin()+turnFinish < 60) {
time t3 = new time();
t3.setHour(q.front.getcurrentStart().getHour());
t3.setMin(q.front.getcurrentStart().getMin()+turnFinish);
q.front.next.setcurrentStart(t3);
}else if(q.front.getcurrentStart().getMin()+turnFinish >= 60){
time t4 = new time();
t4.setHour(q.front.getcurrentStart().getHour()+1);
t4.setMin(q.front.getcurrentStart().getMin()+turnFinish-60);
q.front.next.setcurrentStart(t4);
}
}
if(q.front != q.rear) {
//处理这轮执行的进程:如果已完成时间等于总执行时间,则出队;否则将该进程放在队尾排队等待执行
if(q.front.haveFinish == q.front.getZx()) {
list1.add(q.front);
p.pop(q);
}else if(q.front.haveFinish < q.front.getZx()){
list2.add(q.front);
p.pop(q); //出队
p.add(q, list2.get(0)); //入队尾
list2.clear(); //list2用于每次临时存放队首,使用完应该清零
}
}else if(q.front == q.rear) {
if(q.front.getZx()-q.front.flag*para >= para) {
q.front.flag++;
q.front.haveFinish = q.front.flag*para;
turnFinish = para;
}else if(q.front.getZx()-q.front.flag*para < para){
q.front.haveFinish = q.front.getZx();
turnFinish = q.front.getZx() - q.front.flag*para;
}
q.front.haveFinish = q.front.getZx();
if(q.front.getcurrentStart().getMin()+para < 60) {
time t5 = new time();
t5.setHour(q.front.getcurrentStart().getHour());
t5.setMin(q.front.getcurrentStart().getMin()+para);
q.front.setcurrentStart(t5);
}else if(q.front.getcurrentStart().getMin()+para >= 60){
time t6 = new time();
t6.setHour(q.front.getcurrentStart().getHour()+1);
t6.setMin(q.front.getcurrentStart().getMin()+para-60);
q.front.setcurrentStart(t6);
}
if(q.front.getcurrentStart().getMin()+turnFinish < 60) {
time t1 = new time();
t1.setHour(q.front.getcurrentStart().getHour());
t1.setMin(q.front.getcurrentStart().getMin()+turnFinish);
q.front.setFinish(t1);
}else {
time t2 = new time();
t2.setHour(q.front.getcurrentStart().getHour()+1);
t2.setMin(q.front.getcurrentStart().getMin()+turnFinish-60);
q.front.setFinish(t2);
}
zz = time.sub(q.front.getArrive().getHour()+":"+q.front.getArrive().getMin(),
q.front.getFinish().getHour()+":"+q.front.getFinish().getMin());
q.front.setZz(zz);
q.front.setZzxs((float)q.front.getZz()/q.front.getZx());
sumZz += q.front.getZz();
sumZzxs += q.front.getZzxs();
System.out.println("第" + n + "轮执行和就绪队列的结果:");
System.out.println("ID号 名字 到达时间 总执行时间(分钟) 当前开始时间 已完成时间(分钟) 剩余完成时间(分钟)");
System.out.println(String.format("%-6d",q.front.getId())
+String.format("%-6s",q.front.getName())
+String.format("%-10s",q.front.getArrive().toString())
+String.format("%-13s",q.front.getZx()+"(分钟)")
+String.format("%-9s",q.front.getcurrentStart().toString())
+String.format("%-10d",q.front.haveFinish)
+String.format("%-10d",q.front.getZx()-q.front.haveFinish));
list1.add(q.front);
break;
}
}
System.out.println();
//按完成时间的先后打印进程执行的信息
System.out.println("ID号 名字 到达时间 执行时间(分钟) 首次开始时间 完成时间 周转时间 带权周转时间:");
for(int k=0;k<num;k++) {
loc = 0;
for (int i = 0; i < list1.size(); i++) {
if(time.sub(list1.get(loc).getFinish().toString(),list1.get(i).getFinish().toString()) < 0){
loc = i;
}
}
System.out.println(String.format("%-6d",list1.get(loc).getId())
+String.format("%-6s",list1.get(loc).getName())
+String.format("%-10s",list1.get(loc).getArrive().toString())
+String.format("%-13s",list1.get(loc).getZx()+"(分钟)")
+String.format("%-9s",list1.get(loc).getfirstStart().toString())
+String.format("%-10s",list1.get(loc).getFinish().toString())
+String.format("%-16s",list1.get(loc).getZz()+"(分钟)")
+String.format("%-4.2f",list1.get(loc).getZzxs()));
list1.remove(loc);
}
System.out.println(String.format("%-48s","系统平均周转时间为:")+String.format(" %-4.2f",sumZz/num));
System.out.println(String.format("%-64s","系统带权平均周转时间为: ")+String.format("%-4.2f",sumZzxs/num));
System.out.print("是否继续进程调度实验,开始实验:1,结束实验:0 :");
flag = s.nextInt();
}
System.out.println("进程调度实验结束!!!");
s.close();
}
}
/*
* 实验数据:
5001 p1 1 9:40 20
5004 p4 4 10:10 10
5005 p5 3 10:05 30
5002 p2 3 9:55 15
5003 p3 2 9:45 25
5001 p1 1 19:40 20
5002 p4 2 10:10 10
5003 p5 3 10:05 30
5004 p2 4 9:55 15
5005 p3 5 9:45 25
5006 p6 6 11:40 20
5007 p8 7 12:10 10
5008 p9 8 13:05 30
5009 p10 9 19:55 15
5010 p7 10 7:15 15
* */
运行结果截图
详细算法思想可以参考:Java操作系统进程调度算法——时间片轮转(RR)算法_哆啦有个B梦*的博客-优快云博客_时间片轮转算法的进程状态转换图