操作系统 磁头引臂调度 SCAN算法 JAVA实现

说明

这次实验课太难受了,一个是对JAVA的synchronize、wait、notify等同步的方法不太熟(自信点,把太去了),不过最终也是完全靠自己把这个功能实现了。还有,本人菜鸡,代码不顺眼,嘴下留人。

重要说明

本博客中的代码能运行且结果正确,但是想法是存在问题的,也有博友私信讨论过了。即本次实现时notifyall唤醒的是随机线程,并不是哪个线程提出的请求,哪个线程就来处理该请求。打个比方:线程A、B分别请求122、100。经过本次程序调用最后有可能是线程A把100请求抱走了,而线程B抱走的是122请求。该处理做法是不对的,违反了线程请求的本意,也就是说结果展示里的Thread-0等根本不是真正的线程!


  • 磁头引臂调度算法正确的理解实现见我之后改进的最终版本:https://blog.youkuaiyun.com/guangluo/article/details/108959048

具体要求(看看是不是你需要的做法)

具体要求

运行结果(如果还有别的输出需求的话可以复制下面代码自己改,注释很详尽)

请求队列
调度队列

废话不多说,直接上完整代码(拿去运行)

注意注意,下面这个做了改进,修补了一些问题,还有就是将数组实现换成了ArrayList实现。

package com.guangluo.OS2;

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) {
		for(int i = 0; i < queue.size(); i++) {
			if(orient == 1) {
				if(queue.get(i).dest >= current_dest) {
					if(r == null) r = queue.get(i);
					r = (r.dest < queue.get(i).dest)? r:queue.get(i);
				}
			}
			if(orient == -1) {
				if(queue.get(i).dest <= current_dest) {
					if(r == null) r = queue.get(i);
					r = (r.dest > queue.get(i).dest)? r:queue.get(i);
				}
			}
		}
		if(r == null) {
			orient = -1 * orient;
			return getReq(orient, current_dest);
		}
		Require r2 = r;
		r = null;        // 注意:在把符合规则的第一请求选出来之后,得重新置r为空
		System.out.println("当前执行线程 " + r2.name + "提出的请求");
		return r2;
	}
}

class Scan{
	public int current_dest = 100;
	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);
			Require req = queue.getReq(orient, current_dest);
			System.out.println("-------------------------------------------");
			System.out.print("当前执行的请求为:");
			System.out.println("name:" + req.name + "----" + "dest:" + req.dest);
			System.out.println("磁道位置变换      :" + current_dest + " --> " + req.dest);
			System.out.println("-------------------------------------------");
			current_dest = req.dest;
			
			queue.del(req.name);
			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 Li {
	public static void main(String[] args) {
		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();
			}
		}
	}
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值