java实现操作系统时间片轮转进程调度算法(RR算法)

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梦*的博客-CSDN博客_时间片轮转算法的进程状态转换图

  • 4
    点赞
  • 57
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值