说明
前几次的磁头引臂调度博客写的跟小孩过家家似的,实现起来也并非题目的本意。这次的实现是借鉴了Hansen管程的思想,快抛弃前面的几篇,来看这个~
具体要求
运行结果
完整代码
请求构造类
package com.guangluo.OSDesign;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Random;
import java.util.Set;
import java.util.concurrent.locks.LockSupport;
public class Creator {
public HashMap<Thread, Integer> create() {
HashMap<Thread, Integer> hm = new HashMap<Thread, Integer>(); // 容器:存放 线程-请求 键值对
MyThread mt = new MyThread();
for(int i = 0; i < 8; i++) {
int req = new Random().nextInt(200);
Thread t = new Thread(mt, "Thread_"+i);
t.start();
hm.put(t, req);
}
System.out.println("请求序列: 线程--请求");
Set<Thread> keys = hm.keySet();
for(Thread key: keys) {
System.out.println(key.getName() + " -- " + hm.get(key));
}
return hm;
}
}
class MyThread implements Runnable{
@Override
public void run() {
LockSupport.park(); // 模拟调度的线程被创建后立即进入阻塞状态,等相应的调度算法按调度顺序将他们唤醒
}
}
}
磁盘构造类
package com.guangluo.OSDesign;
public class Disk {
private int currentDist = 100;
private int requireNum = 0;
private static float m = 1; // 跨越一个磁道所用的时间 单位 ms
private int n; // 跨越的磁道数
private static float s = 0; // 启动时间 单位 ms
private static float r = 100; // 磁盘转速 单位r/s
private static int num = 100; // 扇区数
public void set(int rn, int n) {
this.requireNum = rn;
this.n = n;
}
public int getCurrentDist() {
return currentDist;
}
public void setCurrentDist(int newCurrentDist) {
this.currentDist = newCurrentDist;
}
public void showTime() {
float t1 = m * n + s;
float t2 = (float)(1 / (2*r)) * 1000 * requireNum;
float t3 = (float)(1 / (r*num)) * 1000 * requireNum;
float t = t1+ t2 + t3;
System.out.println("----------------");
System.out.println("寻道时间:" + t1);
System.out.println("旋转延迟:" + t2);
System.out.println("传输时间:" + t3);
System.out.println("总用时:" + t);
// System.out.println("当前所在磁道:" + currentDist);
System.out.println("================");
}
}
算法设计类
package com.guangluo.OSDesign;
import java.util.HashMap;
import java.util.Set;
import java.util.concurrent.locks.LockSupport;
public class SCAN {
private int direction = 1; // 1:up -1:down
public static void main(String[] args) {
Creator creator = new Creator();
HashMap<Thread, Integer> hm = creator.create();
int requireNum = hm.size();
Disk disk = new Disk();
SCAN s = new SCAN();
int n = s.scan(hm, disk);
disk.set(requireNum, n);
disk.showTime();
}
public int scan(HashMap<Thread, Integer> hm, Disk disk) {
System.out.println("----------------");
System.out.println("SCAN算法调度序列:");
System.out.println("磁头初始在100位置、移动方向为up");
int[] count = new int[200];
this.require(hm, count);
int n = this.release(hm, count, disk);
return n;
}
public void require(HashMap<Thread, Integer> hm, int[] count) {
Set<Thread> keys = hm.keySet();
for(Thread key: keys) {
// System.out.println(hm.get(key));
count[hm.get(key)] += 1;
// System.out.println(count[hm.get(key)]);
}
}
public int upscan(HashMap<Thread, Integer> hm, int[] count, Disk disk) {
int i = disk.getCurrentDist(), num = 0, absNum = 0;
Thread removeKey = null;
while(i <= 199) {
while(i <= 199 && count[i] == 0) {
i += 1;
absNum += 1;
}
if(i <= 199) {
num += absNum;
absNum = 0;
count[i] -= 1;
Set<Thread> keys = hm.keySet();
for(Thread key: keys) {
if(hm.get(key) == i) {
System.out.println(key.getName() + " -- " + hm.get(key));
// hm.remove(key); // 错误做法
removeKey = key;
LockSupport.unpark(key);
}
}
hm.remove(removeKey);
disk.setCurrentDist(i);
i = disk.getCurrentDist();
}
}
this.direction = -1;
return num;
}
public int downscan(HashMap<Thread, Integer> hm, int[] count, Disk disk) {
int i = disk.getCurrentDist(), num = 0, absNum = 0;
Thread removeKey = null;
while(i >= 0) {
while(i >= 0 && count[i] == 0) {
i -= 1;
absNum += 1;
}
if(i >= 0) {
num += absNum;
absNum = 0;
count[i] -= 1;
Set<Thread> keys = hm.keySet();
for(Thread key: keys) {
if(hm.get(key) == i) {
System.out.println(key.getName() + " -- " + hm.get(key));
removeKey = key;
LockSupport.unpark(key);
}
}
hm.remove(removeKey);
disk.setCurrentDist(i);
i = disk.getCurrentDist();
}
}
this.direction = 1;
return num;
}
public int release(HashMap<Thread, Integer> hm, int[] count, Disk disk) {
int n = 0;
if(this.direction == 1) {
n += this.upscan(hm, count, disk);
n += this.downscan(hm, count, disk);
}
else if(this.direction == -1){
n += this.downscan(hm, count, disk);
n += this.upscan(hm, count, disk);
}
return n;
}
}