本次操作系统试验是使用程序来模拟操作系统中进程调度的不同的调度策略,分别为FIFO先进先出,SJF最短时间优先,RR时间片轮换以及HRRN最高响应比算法。
模拟的情况下,进程数为8,进程所需执行时间为随机产生的整数,单位为S,默认进程同时到达。
代码:
package process;
import java.util.ArrayList;
import java.util.List;
public class Process {
public static List<double[]> taskInfo = new ArrayList<double[]>();//进程列表
public static int taskNum = 8;//进程数目
public static void initTask()
{
for(int i=0;i<taskNum;i++)
{
double[] t=new double[4];
t[0]=i;//进程号
t[1]=0;//到达时间
t[2]=0;//响应比
t[3]=(int)(Math.random()*100)%20+1;//需要运行时间
taskInfo.add(t);
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Process.initTask();
System.out.println("最短作业优先================================================");
SJF sjf = new SJF();
sjf.initTask(taskInfo,taskNum);
sjf.SJFShow();//最短作业优先
System.out.println("时间片轮转调度================================================");
RR rr = new RR();
rr.initTask(taskInfo);
rr.circleTime();
System.out.println("最高相应比策略================================================");
HRRN hrrn = new HRRN();
hrrn.initTask(taskInfo,taskNum);
hrrn.HRRNShow();
System.out.println("先进先出策略================================================");
FIFO fifo = new FIFO();
fifo.initTask(taskInfo);
fifo.FIFOShow();
}
}
package process;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
public class FIFO {
private SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm:ss");
private int taskNum = 8;
public ArrayBlockingQueue<double[]> taskQueue = new ArrayBlockingQueue<>(taskNum);
private List<double[]> executeTime = new ArrayList<>();
public void FIFOShow(){
try {
while(true){
double [] task = new double[4];
task = taskQueue.take();
int taskNo = (int) task[0];
int CurrentTaskTime = (int)task[3];
System.out.println(timeFormat.format(new Date())+":第"+taskNo+"任务开始执行……");
Thread.sleep(CurrentTaskTime*1000);
System.out.println(timeFormat.format(new Date())+"结束执行 用时:"+CurrentTaskTime+"s");
double []executeTask = new double[2];
executeTask[0] = taskNo;
executeTask[1] = System.currentTimeMillis()-task[1];
executeTime.add(executeTask);
if(taskQueue.size()==0){
break;
}
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
showTime();
}
public void showTime() {
// TODO Auto-generated method stub
double sumTime = 0;
for (int i = 0; i < executeTime.size(); i++) {
double []task = executeTime.get(i);
System.out.println("task:"+(int)task[0]+":周转周期 = "+(int)(task[1]/1000)+"s");
sumTime += task[1];
}
System.out.println("使用先进先出策略,平均周转周期为:"+(int)(sumTime/executeTime.size()/1000)+"s");
}
public void initTask(List<double []> initTask)//初始化进程列表
{
for(int i=0;i<initTask.size();i++)
{
double [] task=initTask.get(i);
task[1] = System.currentTimeMillis();//获得进程到达时间
try {
taskQueue.put(task);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
package process;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class SJF {
private int taskNum = 8;
public List<double[]> taskTime = new ArrayList<>();//
private SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm:ss");
private List<double[]> executeTime = new ArrayList<>();
public void SJFShow(){
for (int i = 0; i < taskNum; i++) {
try {
double [] task = get_task(taskTime);
System.out.println(timeFormat.format(new Date())+":第"+(int) task[0]+"任务开始执行……");
Thread.sleep(1000*(int) task[3]);
System.out.println(timeFormat.format(new Date())+"执行完成 用时:"+(int) task[3]+"s");
double executeTime = System.currentTimeMillis()-task[1];
double [] e = new double[2];
e[0] = (int)task[0];
e[1] = executeTime;
this.executeTime.add(e);
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
showTime();
}
public void showTime() {
// TODO Auto-generated method stub
double sumTime = 0;
for (int i = 0; i < executeTime.size(); i++) {
double []task = executeTime.get(i);
System.out.println("task:"+(int)task[0]+"周转时间:"+(int)(task[1]/1000)+"s");
sumTime+=task[1];
}
System.out.println("使用最短作业优先策略,平均周转时间为:"+(int)(sumTime/executeTime.size()/1000)+"s");
}
public double[] get_task(List<double[]> taskTime2) {
// TODO Auto-generated method stub
double [] task = new double[4];
double smallestTime = 50;//运行时间
int temp = -1;
for (int i = 0; i < taskTime2.size(); i++) {
if(taskTime2.get(i)[3] < smallestTime){
smallestTime = taskTime2.get(i)[3];
temp = i;
}
}
task = taskTime2.get(temp);
taskTime2.remove(temp);
return task;
}
public void initTask(List<double[]> taskInfo, int taskNum){
this.taskNum = taskNum;
for (int i = 0; i < this.taskNum; i++) {
double [] task = taskInfo.get(i);
task[1] = System.currentTimeMillis();
this.taskTime.add(task);
}
}
}
package process;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
public class RR {
private SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm:ss");
private int taskNum = 8;
private int circleSize = 4;
public ArrayBlockingQueue<double[]> taskQueue = new ArrayBlockingQueue<>(taskNum);
private List<double[]> executeTime = new ArrayList<>();
public void circleTime(){
try {
while(true){
double [] task = new double[4];
task = taskQueue.take();
int CurrentTaskTime = (int)task[3];
int taskNo = (int)task[0];
System.out.println(timeFormat.format(new Date())+":第"+taskNo+"任务开始执行……");
if(CurrentTaskTime < circleSize){//如果可以在时间片内运行
Thread.sleep(CurrentTaskTime*1000);
System.out.println(timeFormat.format(new Date())+"结束执行 用时:"+CurrentTaskTime+"s");
double []executeTask = new double[2];
executeTask[0] = taskNo;
executeTask[1] = System.currentTimeMillis()-task[1];
executeTime.add(executeTask);
}else{//不能在本时间片中运行
task[3] = task[3] - circleSize;
taskQueue.put(task);
Thread.sleep(circleSize*1000);
System.out.println(timeFormat.format(new Date())+"本时间片用完,进程等待");
}
if(taskQueue.size() == 0){
break;
}
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
showTime();
}
public void showTime() {
// TODO Auto-generated method stub
double sumTime = 0;
for (int i = 0; i < executeTime.size(); i++) {
double []task = executeTime.get(i);
System.out.println("task:"+(int)task[0]+":周转周期 = "+(int)(task[1]/1000)+"s");
sumTime += task[1];
}
System.out.println("使用时间片轮转策略,平均周转周期为:"+(int)(sumTime/executeTime.size()/1000)+"s");
}
public void initTask(List<double []> initTask)//初始化进程列表
{
for(int i=0;i<initTask.size();i++)
{
double [] task=initTask.get(i);
task[1] = System.currentTimeMillis();//获得进程到达时间
try {
taskQueue.put(task);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
package process;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class HRRN {
private static SimpleDateFormat timeFormat= new SimpleDateFormat("HH:mm:ss");
public static List<double []> taskInfo=new ArrayList<>();//进程信息列表
public static int task_num=8;//进程数
private static List<double[]> executeTime = new ArrayList<>();//进程周转时间列表
public void HRRNShow(){
for (int i = 0; i < task_num; i++) {
getRatio();
double []currentTask = getATaskOfHign();
System.out.println(timeFormat.format(new Date())+"第"+(int)currentTask[0]+"任务正在执行……");
try {
Thread.sleep((long) (currentTask[3]*1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(timeFormat.format(new Date())+"任务运行结束 用时: "+currentTask[3]+"s");
double [] execTask = new double[4];
execTask[0] = currentTask[0];
execTask[1] = System.currentTimeMillis()-currentTask[1];
executeTime.add(execTask);
}
showTime();
}
public void showTime() {
// TODO Auto-generated method stub
double sumTime = 0;
for (int i = 0; i < executeTime.size(); i++) {
double [] temp = executeTime.get(i);
System.out.println("task:"+(int)temp[0]+"周转时间="+(int)(temp[1]/1000)+"s");
sumTime+=temp[1];
}
System.out.println("使用最高相应比策略,平均周转时间"+(int)(sumTime/executeTime.size()/1000)+"s");
}
private double[] getATaskOfHign() {
// TODO Auto-generated method stub
double [] tempTask = new double[4];
double max_ratio = 0;
int No = -1;
for (int i = 0; i < taskInfo.size(); i++) {
if (taskInfo.get(i)[2] > max_ratio) {
tempTask = taskInfo.get(i);
max_ratio = taskInfo.get(i)[2];
No = i;
}
}
taskInfo.remove(No);
return tempTask;
}
public void getRatio() {
// TODO Auto-generated method stub
for (int i = 0; i < taskInfo.size(); i++) {
double []task = taskInfo.get(i);
taskInfo.remove(i);
double ratio = (System.currentTimeMillis()-task[1])/task[3]+1;
task[2] = ratio;
taskInfo.add(task);
}
}
public void initTask(List<double[]> taskInfo,int tn){
task_num=tn;
for(int i=0;i<taskInfo.size();i++)
{
double[] task=taskInfo.get(i);
task[1]=System.currentTimeMillis();//获得进程到达时间
HRRN.taskInfo.add(task);
}
}
}