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

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

具体要求

在这里插入图片描述

代码~

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值