import java.util.*;
/**
* 优先级调度算法
*
* @author 徐鑫
* @date 2022/05/20
*/
public class Main1 {
static List<PCB> run = new ArrayList<>(); //运行队列
static List<PCB> finash = new ArrayList<>();//完成队列
static List<PCB> ready = new ArrayList<>();//就绪队列
static int cpuTime = 0;//cpu运行时间
/**
* 主方法
*/
public static void main(String[] args) {
initData();//初始化随机数据
doPcb();//执行
}
/**
* 执行
*/
private static void doPcb() {
Scanner scanner = new Scanner(System.in);
while (!run.isEmpty()) { //当有进程处于运行状态时重复执行
//阻塞,输入一次执行一次,方便查看过程
System.out.println("任意数字键继续");
scanner.nextInt();
cpuTime++; //cpu时间增加
run.get(0).prio -= 3; //进程优先级减3
run.get(0).needt--; //进程运行所需时间减一
if (run.get(0).needt == 0) { //当进程运行结束时
run.get(0).state = STATE.FINISH; //设置成完成状态
finash.add(run.get(0)); //添加至完成队列
run.remove(0); //从运行队列中移出
if (!ready.isEmpty()) { //就绪队列如果还有进程
run.add(ready.get(0)); //将第一个进程放入运行队列
ready.get(0).state = STATE.RUN; //设置其为运行状态
ready.remove(0); //再从就绪队列中移出
}
} else { //这个线程执行一次还没运行完成时
if (!ready.isEmpty()) { //就绪队列不为空
if (run.get(0).prio < ready.get(0).prio) { //判断就绪队列第一个和运行的哪一个优先级高
ready.get(0).state = STATE.RUN; //就绪状态切换为运行
run.get(0).state = STATE.READY; //运行的进程状态切换回就绪
ready.add(run.get(0)); //将运行的进程放回就绪里
run.remove(0); //将进程移出运行队列
run.add(ready.get(0)); //把就绪的第一个进程放入运行队列中
ready.remove(0); //移出就绪队列
}
}
}
Collections.sort(ready); //按优先级大小排序(降序)
printMessage(); //打印信息
}
}
/**
* 初始化数据
*/
private static void initData() {
List<PCB> pcbs = new ArrayList<>();
Random random = new Random();
for (int i = 0; i < 10; i++) {
pcbs.add(new PCB("线程" + i, 1 + random.nextInt(10)));
}
for (int i = 0; i < pcbs.size(); i++) {
ready.add(pcbs.get(i));
}
Collections.sort(ready);
System.out.println("-------------------------数据初始化完成------------------------");
System.out.println("线程标识符\t进程优先级\t进程占用时间\t完成还需要时间\t进程状态");
for (PCB pcb : ready) {
System.out.println(" " + pcb.name + "\t\t\t" + pcb.prio + "\t\t\t" + pcb.cput + "\t\t\t" + pcb.needt + "\t\t\t" + pcb.state);
}
System.out.println("-------------------------------------------------------------");
ready.get(0).state = STATE.RUN;
run.add(ready.get(0));
ready.remove(0);
Collections.sort(ready);
printMessage();
}
/**
* 打印信息
*/
private static void printMessage() {
System.out.println();
System.out.println("----------------------------就绪队列--------------------------");
System.out.println("线程标识符\t进程优先级\t进程占用时间\t完成还需要时间\t进程状态");
for (PCB pcb : ready) {
System.out.println(" " + pcb.name + "\t\t\t" + pcb.prio + "\t\t\t" + pcb.cput + "\t\t\t" + pcb.needt + "\t\t\t" + pcb.state);
}
System.out.println("----------------------------运行队列--------------------------");
for (PCB pcb : run) {
System.out.println(" " + pcb.name + "\t\t\t" + pcb.prio + "\t\t\t" + pcb.cput + "\t\t\t" + pcb.needt + "\t\t\t" + pcb.state);
}
System.out.println("----------------------------完成队列--------------------------");
for (PCB pcb : finash) {
System.out.println(" " + pcb.name + "\t\t\t" + pcb.prio + "\t\t\t" + pcb.cput + "\t\t\t" + pcb.needt + "\t\t\t" + pcb.state);
}
System.out.println("-------------------------------------------------------------");
System.out.println("CPU时间:" + cpuTime);
System.out.println("-------------------------------------------------------------");
System.out.println();
}
/**
* 枚举状态
*/
enum STATE {
RUN, FINISH, READY//
}
/**
* 描述进程
*/
static class PCB implements Comparable<PCB> {
String name; //进程标识符
int prio; //进程优先级
int cput; //进程占用的CPU时间
int needt; //进程离完成还需要的CPU时间
STATE state; //进程状态(运行、完成和就绪)
public PCB(String name, int cput) {
this.name = name;
this.prio = 30 - cput;
this.cput = cput;
this.needt = cput;
this.state = STATE.READY;
}
/**
* 比较器
*
* @param o PCB
* @return int
*/
@Override
public int compareTo(PCB o) {
return o.prio - this.prio;
}
}
}
运行结果图:
初始化
过程:按一次数字键执行一次