最近做操作系统的课程设计,网上看到一些动态调度的算法都是基于C写的,下午闲来无事,用Java写了一个高优先级调度的算法玩玩,这个算法首先有这几条要注意
- 优先级是否可以为负的,答案是肯定的,如果有一个线程阻塞了另外一个线程一直去运行就可能一直减去,让优先级变成负数了
- 阻塞的时机:可以说阻塞的时机特别的重要,一旦到达时间需要线程进行阻塞的状态就要立刻将状态改变掉,让它产生调度
- 恢复成就绪状态的问题:因为是有可能是线程进行I/O操作,让其阻塞了,所以说,一个时间片就需要让恢复阻塞的时间常数+1,当变为0的时候让他进入调度状态
- 如果在系统中都是阻塞的线程怎么办?那没有办法,操作系统只能干等着让他们变为就绪状态的时候才能运行
先上一个PCB结构体函数块
public class PCB {//进程的IDprivate long id;//优先级顺序private int priority;// 运行的cpu时间private long cputime;// 需要运行的时间private long alltime;// 即将阻塞的时间private long startblock;// 从阻塞中回复的时间private long blocktime;// 现在线程的状态private String state;public PCB(long id, int priority, long cputime, long alltime,long startblock, long blocktime, String state) {super();this.id = id;this.priority = priority;this.cputime = cputime;this.alltime = alltime;this.startblock = startblock;this.blocktime = blocktime;this.state = state;}public String getState() {return state;}public void setState(String state) {this.state = state;}public long getBlocktime() {return blocktime;}public void setBlocktime(long blocktime) {this.blocktime = blocktime;}
// 运行的三个状态public final static String STATE_READY = "READY";public final static String STATE_RUN = "RUN";public final static String STATE_BLOCK = "BLOCK";public long getId() {return id;}public void setId(long id) {this.id = id;}public int getPriority() {return priority;}public void setPriority(int priority) {this.priority = priority;}public long getCputime() {return cputime;}public void setCputime(long cputime) {this.cputime = cputime;}public long getAlltime() {return alltime;}public void setAlltime(long alltime) {this.alltime = alltime;}public long getStartblock() {return startblock;}public void setStartblock(long startblock) {this.startblock = startblock;}}
好了,现在是主要的线程调度算法,注意优先级的调整:
import java.util.ArrayList;import java.util.Arrays;import java.util.Comparator;import java.util.Iterator;import java.util.List;public class OrderImitate {// 按优先级次序排列的数组private ArrayList<PCB> priorityArrayList = null;/*** 优先级排序*/public void sortArray(){PCB[] pcbs = (PCB[])priorityArrayList.toArray(new PCB[priorityArrayList.size()]);Arrays.sort(pcbs, new MyComprator());List<PCB> list = Arrays.asList(pcbs);this.priorityArrayList = new ArrayList<PCB>(list);}/*** 初始化,按照书中的数据进行初始化操作*/private void init(){priorityArrayList = new ArrayList<PCB>();PCB zero = new PCB(0, 9, 0, 3, 2, 3, PCB.STATE_READY);priorityArrayList.add(zero);PCB one = new PCB(1, 38, 0, 3, -1, 0, PCB.STATE_READY);priorityArrayList.add(one);PCB two = new PCB(2, 30, 0, 6, -1, 0, PCB.STATE_READY);priorityArrayList.add(two);PCB three = new PCB(3, 29, 0, 3, -1, 0, PCB.STATE_READY);priorityArrayList.add(three);PCB four = new PCB(4, 0, 0, 4, -1, 0, PCB.STATE_READY);priorityArrayList.add(four);sortArray();}/*** 优先级执行算法* @return*/public boolean hightpPriority(){// 获得第一个元素PCB first = priorityArrayList.get(0);if(!first.getState().equals(PCB.STATE_BLOCK)){// 运行一次优先级顺序-3first.setPriority(first.getPriority()-3);first.setCputime(first.getCputime()+1);first.setAlltime(first.getAlltime()-1);// 是否进入阻塞状态if(first.getStartblock() > 0){first.setStartblock(first.getStartblock() - 1);}// 当是阻塞状态的时候,将状态变为阻塞if(first.getStartblock() == 0){first.setState(PCB.STATE_BLOCK);}}// 所需要的时间片完成,结束运行if(first.getAlltime() == 0){System.out.println("----------------------------------------------");System.out.println("ID " + first.getId() + " have done !");System.out.println("----------------------------------------------");priorityArrayList.remove(0);}// 后面的任务优先级+1Iterator<PCB> iterator = priorityArrayList.iterator();int count = 0;while(iterator.hasNext()){if(count == 0){count++;iterator.next();continue;}PCB pcb = iterator.next();pcb.setPriority(pcb.getPriority()+1);// PCB的阻塞状态改变if(pcb.getBlocktime() != 0 && pcb.getState().equals(PCB.STATE_BLOCK)){pcb.setBlocktime(pcb.getBlocktime() -1);if(pcb.getBlocktime() == 0){pcb.setState(PCB.STATE_READY);}}}sortArray();return true;}/*** 执行程序*/public void startRuning(){while(hightpPriority()){if(this.priorityArrayList.size() == 0){System.out.println("-----------------> ALL Works have done !");break;}// 输出数据Iterator<PCB> iterator = priorityArrayList.iterator();System.out.println("-----------------------------------------------------------------------------------------");System.out.println("ID PRIORITY CPUTIME ALLTIME STARTBLOCK BLOCKTIME STATE");while(iterator.hasNext()){PCB pcb = iterator.next();System.out.printf("%d %8d %12d %12d %13d %14d %18s ", pcb.getId(),pcb.getPriority(), pcb.getCputime(),pcb.getAlltime(), pcb.getStartblock(),pcb.getBlocktime(), pcb.getState());}System.out.println("-----------------------------------------------------------------------------------------");}}public static void main(String[] args) {OrderImitate orderImitate = new OrderImitate();orderImitate.init();orderImitate.startRuning();}// 优先级次序调整,优先级高且没有阻塞的进程在前面class MyComprator implements Comparator<PCB> {public int compare(PCB o1, PCB o2) {if((o1.getState().equals(PCB.STATE_READY) && o2.getState().equals(PCB.STATE_READY)) || (o1.getState().equals(PCB.STATE_BLOCK) && o2.getState().equals(PCB.STATE_BLOCK))){if(o1.getPriority() == o2.getPriority() ){return 0;}else if(o1.getPriority() > o2.getPriority()){return -1;}else {return 1;}}else if(o1.getState().equals(PCB.STATE_BLOCK) && o2.getState().equals(PCB.STATE_READY)){return 1;}else{return -1;}}}}
一开始是想用优先队列的,但是碰上个问题,如果有多个线程同时进入阻塞状态,那么就可能第二个到后面那个都无法运行,这样没有完全排好序的优先队列就没有办法使用了,而且优先队列碰上一个大的问题,不知道什么,中途修改了队列中的值没有触发队列的排序,导致后面的一系列次序无法进行。
好的,现在看看最后的结果:
-----------------------------------------------------------------------------------------ID PRIORITY CPUTIME ALLTIME STARTBLOCK BLOCKTIME STATE1 35 1 2 -1 0 READY2 31 0 6 -1 0 READY3 30 0 3 -1 0 READY0 10 0 3 2 3 READY4 1 0 4 -1 0 READY----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ID PRIORITY CPUTIME ALLTIME STARTBLOCK BLOCKTIME STATE1 32 2 1 -1 0 READY2 32 0 6 -1 0 READY3 31 0 3 -1 0 READY0 11 0 3 2 3 READY4 2 0 4 -1 0 READY---------------------------------------------------------------------------------------------------------------------------------------ID 1 have done !---------------------------------------------------------------------------------------------------------------------------------------ID PRIORITY CPUTIME ALLTIME STARTBLOCK BLOCKTIME STATE2 32 0 6 -1 0 READY3 32 0 3 -1 0 READY0 12 0 3 2 3 READY4 3 0 4 -1 0 READY----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ID PRIORITY CPUTIME ALLTIME STARTBLOCK BLOCKTIME STATE3 33 0 3 -1 0 READY2 29 1 5 -1 0 READY0 13 0 3 2 3 READY4 4 0 4 -1 0 READY----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ID PRIORITY CPUTIME ALLTIME STARTBLOCK BLOCKTIME STATE3 30 1 2 -1 0 READY2 30 1 5 -1 0 READY0 14 0 3 2 3 READY4 5 0 4 -1 0 READY----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ID PRIORITY CPUTIME ALLTIME STARTBLOCK BLOCKTIME STATE2 31 1 5 -1 0 READY3 27 2 1 -1 0 READY0 15 0 3 2 3 READY4 6 0 4 -1 0 READY----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ID PRIORITY CPUTIME ALLTIME STARTBLOCK BLOCKTIME STATE2 28 2 4 -1 0 READY3 28 2 1 -1 0 READY0 16 0 3 2 3 READY4 7 0 4 -1 0 READY----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ID PRIORITY CPUTIME ALLTIME STARTBLOCK BLOCKTIME STATE3 29 2 1 -1 0 READY2 25 3 3 -1 0 READY0 17 0 3 2 3 READY4 8 0 4 -1 0 READY---------------------------------------------------------------------------------------------------------------------------------------ID 3 have done !---------------------------------------------------------------------------------------------------------------------------------------ID PRIORITY CPUTIME ALLTIME STARTBLOCK BLOCKTIME STATE2 25 3 3 -1 0 READY0 18 0 3 2 3 READY4 9 0 4 -1 0 READY----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ID PRIORITY CPUTIME ALLTIME STARTBLOCK BLOCKTIME STATE2 22 4 2 -1 0 READY0 19 0 3 2 3 READY4 10 0 4 -1 0 READY----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ID PRIORITY CPUTIME ALLTIME STARTBLOCK BLOCKTIME STATE0 20 0 3 2 3 READY2 19 5 1 -1 0 READY4 11 0 4 -1 0 READY----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ID PRIORITY CPUTIME ALLTIME STARTBLOCK BLOCKTIME STATE2 20 5 1 -1 0 READY0 17 1 2 1 3 READY4 12 0 4 -1 0 READY---------------------------------------------------------------------------------------------------------------------------------------ID 2 have done !---------------------------------------------------------------------------------------------------------------------------------------ID PRIORITY CPUTIME ALLTIME STARTBLOCK BLOCKTIME STATE0 17 1 2 1 3 READY4 13 0 4 -1 0 READY----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ID PRIORITY CPUTIME ALLTIME STARTBLOCK BLOCKTIME STATE4 14 0 4 -1 0 READY0 14 2 1 0 3 BLOCK-----------------------------------------------------------------------------------------可以看到这里因为线程阻塞产生了调度:-----------------------------------------------------------------------------------------ID PRIORITY CPUTIME ALLTIME STARTBLOCK BLOCKTIME STATE4 11 1 3 -1 0 READY0 15 2 1 0 2 BLOCK----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ID PRIORITY CPUTIME ALLTIME STARTBLOCK BLOCKTIME STATE4 8 2 2 -1 0 READY0 16 2 1 0 1 BLOCK----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ID PRIORITY CPUTIME ALLTIME STARTBLOCK BLOCKTIME STATE0 17 2 1 0 0 READY4 5 3 1 -1 0 READY---------------------------------------------------------------------------------------------------------------------------------------ID 0 have done !---------------------------------------------------------------------------------------------------------------------------------------ID PRIORITY CPUTIME ALLTIME STARTBLOCK BLOCKTIME STATE4 5 3 1 -1 0 READY---------------------------------------------------------------------------------------------------------------------------------------ID 4 have done !---------------------------------------------------------------> ALL Works have done !