import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
/**
* 时间片轮转
*
* @author 徐鑫
* @date 2022/05/20
*/
public class Main2 {
static int timeSlice;//时间片
static List<PCB> unloaded = new ArrayList<>(); //未加载队列
static List<PCB> ready = new ArrayList<>(); //就绪队列
static List<PCB> finish = new ArrayList<>(); //完成队列
static int cpuTime = 0; //cpu运行时间
static String[] result = new String[150]; //结果集
/**
* 主方法
*/
public static void main(String[] args) {
initData(); //初始化随机数据
doPCB(); //执行
}
/**
* 执行
*/
private static void doPCB() {
while (true) {
cpuTime++; //cpu时间加增加
loadingNotLoadingProcess();//当cpu时间增加时,首先看为加载队列是否可以加载进入就绪队列
if (!ready.isEmpty()) {
//就绪队列不为空
PCB pcb = ready.get(0);
for (int i = timeSlice; i > 0; i--) { //遍历时间片
pcb.needTime--; //pcb的还需要的完成时间减一
result[cpuTime] = pcb.name; //方便查看结果,记录一下
if (pcb.needTime == 0 || i == 1) //当时间片用完或者线程运行结束
break;
//时间片还没用完,线程也没结束,则cpu时间增加并且查看是否有加入的新进程
cpuTime++;
loadingNotLoadingProcess();
}
if (pcb.needTime != 0) {
//时间片用完了并且进程没结束,将该进程移动到最后
ready.remove(0);
ready.add(pcb);
} else {
//线程结束了,移出就绪队列到完成队列中
ready.remove(0);
finish.add(pcb);
}
}
if (cpuTime == 100) { //当cpu运行时间差不多了就结束循环吧,可以打印结果了
int end = 100;
//用于获取最后线程结束的大概位置(连续5个空),不然打印结果太长,有很多没用的空数据
for (int i = 0; i <= 100; i++) {
if (result[i].equals("空")) {
if (result[i + 1].equals("空")) {
if (result[i + 2].equals("空")) {
if (result[i + 3].equals("空")) {
if (result[i + 4].equals("空")) {
end = i;
break;
}
}
}
}
}
}
String[] temp = new String[end + 1];
System.arraycopy(result, 0, temp, 0, end + 1);
System.out.println(Arrays.toString(temp));
break;
}
}
}
/**
* //当cpu时间增加时,首先看为加载队列是否可以加载进入就绪队列
*/
private static void loadingNotLoadingProcess() {
for (int i = 0; i < unloaded.size(); i++) {
PCB pcb = unloaded.get(i);
if (pcb.timeOfArrival == cpuTime) {
ready.add(pcb);
unloaded.remove(pcb);
i--;
}
}
}
/**
* 初始化数据
*/
private static void initData() {
Random random = new Random();
timeSlice = 2 + random.nextInt(4);//时间片随机2-5
for (int i = 1; i <= 10; i++) {
String name = "进程" + i;
int timeOfArrival = 1 + random.nextInt(10);//到达时间1-10
int runningTime = 1 + random.nextInt(10);//运行时间1-10
unloaded.add(new PCB(name, timeOfArrival, runningTime, STATE.UNLOADED));
}
unloaded.sort((o1, o2) ->
o1.timeOfArrival - o2.timeOfArrival
);
System.out.println("-------------------------数据初始化完成------------------------");
System.out.println("线程标识符\t到达时间\t运行时间\t进程状态");
for (PCB pcb : unloaded) {
System.out.println(pcb.name + "\t\t" + pcb.timeOfArrival + "\t\t" + pcb.runningTime + "\t\t" + pcb.state);
}
System.out.println("-------------------------------------------------------------");
System.out.println("时间片:" + timeSlice);
System.out.println("-------------------------------------------------------------");
Arrays.fill(result, "空");
}
/**
* 状态枚举
*/
enum STATE {
RUN, FINISH, READY, UNLOADED
}
/**
* 用于描述进程
*/
static class PCB {
String name; //进程标识符
int timeOfArrival; //到达时间
int runningTime; //运行时间
int needTime; //剩余时间
STATE state; //进程状态(运行、完成和就绪)
/**
* 初始化构造函数
*
* @param name 名字
* @param timeOfArrival 到达时间
* @param runningTime 运行时间
* @param state 状态
*/
public PCB(String name, int timeOfArrival, int runningTime, STATE state) {
this.name = name;
this.timeOfArrival = timeOfArrival;
this.runningTime = runningTime;
this.state = state;
this.needTime = runningTime;
}
}
}
附上图片
结果集太长,没有换行,有需要自己改哈