具体要求
代码~
package com.guangluo.OS;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Random;
class Require{
public String name;
public int dest;
public Require(String name, int dest) {
this.name = name;
this.dest = dest;
}
public void setName(String name) {
this.name = name;
}
public void setDest(int dest) {
this.dest = dest;
}
@Override
public String toString() {
return name + " " + dest;
}
}
class Queue{
public ArrayList<Require> queue = null;
public Require r = null;
public Queue(ArrayList<Require> queue) {
this.queue = queue;
}
public void add(Require req) {
queue.add(req);
}
public void del(String name) {
Iterator<Require> iterator = queue.iterator();
while(iterator.hasNext()) {
Require req = iterator.next();
if(req.name == name)
iterator.remove();
}
}
public boolean isNull() {
if(queue == null)
return true;
return false;
}
public void show() {
Iterator<Require> iterator = queue.iterator();
while(iterator.hasNext()) {
System.out.println(iterator.next().toString());
}
}
public Require getReq(int orient, int current_dest) {
Require r0 = null, r1 = null, r2 = null;
// System.out.println("-----------------");
// System.out.println("当前请求队列为:");
// this.show();
// System.out.println("-----------------");
// System.out.println("磁头前进方向上的请求与其相对应的磁头间距为:");
for(int i = 0; i < queue.size(); i++) {
if(orient == 1) {
if(queue.get(i).dest >= current_dest && queue.get(i).dest < 100) {
if(r1 == null) r1 = queue.get(i);
r1 = (r1.dest < queue.get(i).dest)? r1:queue.get(i);
// System.out.println(queue.get(i).name + "与磁头" + current_dest + " 相距:" + (queue.get(i).dest - current_dest));
}else if(queue.get(i).dest >= current_dest + 100) {
if(r2 == null) r2 = queue.get(i);
r2 = (r2.dest < queue.get(i).dest)? r2:queue.get(i);
// System.out.println(queue.get(i).name + "与磁头" + (current_dest + 100) + " 相距:" + (queue.get(i).dest - current_dest - 100));
}
}
if(orient == -1) {
if(queue.get(i).dest <= current_dest && queue.get(i).dest >= 0) {
if(r1 == null) r1 = queue.get(i);
r1 = (r1.dest > queue.get(i).dest)? r1:queue.get(i);
// System.out.println(queue.get(i).name + "与磁头" + current_dest + " 相距:" + (current_dest - queue.get(i).dest));
}else if(queue.get(i).dest <= current_dest + 100) {
if(r2 == null) r2 = queue.get(i);
r2 = (r2.dest > queue.get(i).dest)? r2:queue.get(i);
// System.out.println(queue.get(i).name + "与磁头" + (current_dest + 100) + " 相距:" + (current_dest + 100 - queue.get(i).dest));
}
}
}
if(r1 == null && r2 == null) {
orient = -1 * orient;
return getReq(orient, current_dest);
}
if(orient == 1) {
if(r1 == null) r0 = r2;
else if(r2 == null) r0 = r1;
else r0 = (r1.dest - current_dest <= r2.dest - current_dest - 100)? r1: r2;
}else {
if(r1 == null) r0 = r2;
else if(r2 == null) r0 = r1;
else r0 = (current_dest - r1.dest <= current_dest + 100 - r2.dest)? r1: r2;
}
return r0;
}
}
class Scan{
public int current_dest = 34;
public int orient = 1;
public boolean isNull = true; // 表示磁盘是否可访问
public Queue queue = null;
public boolean flag = true; // 表示请求队列是否为空
public Scan(Queue queue) {
this.queue = queue;
}
public void require(int dest) {
System.out.print("当前入队请求:");
System.out.println(Thread.currentThread().getName() + " " + dest);
Require req = new Require(Thread.currentThread().getName(), dest);
if(flag == true) {
ArrayList<Require> q2 = new ArrayList<Require>();
q2.add(req);
queue = new Queue(q2);
flag = false;
}else {
queue.add(req);
}
System.out.println("当前请求队列为:");
queue.show();
}
public synchronized void release() throws InterruptedException{
if(isNull) {
isNull = false;
Thread.sleep(1000);
System.out.println("-------------------------------------------");
Require req = queue.getReq(orient, current_dest);
System.out.print("当前执行的请求为:");
System.out.println("name:" + req.name + "----" + "dest:" + req.dest);
if(req.dest < 100)
current_dest = req.dest;
else
current_dest = req.dest - 100;
System.out.println("双磁头磁道位置为:" + current_dest + "---" + (current_dest + 100));
queue.del(req.name);
System.out.println("-------------------------------------------");
if(queue.isNull() == true) {
System.out.println("请求队列已经空了");
flag = true;
}
isNull = true;
notifyAll();
}else {
wait();
}
}
}
class MyThread implements Runnable{
public Scan scan;
public MyThread(Scan scan) {
this.scan = scan;
}
@Override
public void run() {
boolean flag = true;
while(flag) {
flag = false;
scan.require(new Random().nextInt(200));
System.out.println("===============================");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
scan.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class Lei {
public static void main(String[] args) {
System.out.println("双磁头初始位置:34---134,初始前进方向:由小到大");
Queue queue = null;
Scan scan = new Scan(queue);
for(int i = 0; i < 12; i++) {
Thread t = new Thread(new MyThread(scan));
t.start();
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
说明
主要是对同方向且距离最近磁道请求的选取,因为是双磁头引臂,所以需要多加考虑。
重要说明
本博客中的代码能运行且结果正确,但是想法是存在问题的,也有博友私信讨论过了。即本次实现时notifyall唤醒的是随机线程,并不是哪个线程提出的请求,哪个线程就来处理该请求。打个比方:线程A、B分别请求122、100。经过本次程序调用最后有可能是线程A把100请求抱走了,而线程B抱走的是122请求。该处理做法是不对的,违反了线程请求的本意,也就是说结果展示里的Thread-0等根本不是真正的线程!
- 磁头引臂调度算法正确的理解实现见我之后改进的最终版本:https://blog.csdn.net/guangluo/article/details/108959048