文章目录
- 实验内容
- 实验目的
- 实验原理
- 完整代码+测试
实验内容
- 模拟电梯调度算法,实现对磁盘的调度。
实验目的
- 磁盘是一种高速、大量旋转型、可直接存取的存储设备。它作为计算机系统的辅助存储器,负担着繁重的输入输出任务,在多道程序设计系统中,往往同时会有若干个要求访问磁盘的输入输出请示等待处理。系统可采用一种策略,尽可能按最佳次序执行要求访问磁盘的诸输入输出请求,这就叫磁盘调度,使用的算法称磁盘调度算法。磁盘调度能降低为若干个输入输出请求服务所须的总时间,从而提高系统效率。本实验要求学生模拟设计一个磁盘调度程序,观察磁盘调度程序的动态运行过程。
实验原理
- 模拟电梯调度算法,对磁盘调度。
磁盘是要供多个进程共享的存储设备,但一个磁盘每个时刻只能为一个进程服务。
当有进程在访问某个磁盘时,其他想访问该磁盘的进程必须等待,直到磁盘一次工作结束。
当有多个进程提出输入输出请求处于等待状态,可用电梯调度算法从若干个等待访问者中选择一个进程,让它访问磁盘。当存取臂仅需移到一个方向最远的所请求的柱面后,如果没有访问请求了,存取臂就改变方向。
完整代码+测试
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;
//这是一个磁头里面描述此时他在哪个下标 并且是往左方向走还是右方向
class Head {
public int index;
public String direction;
public Head(int index, String direction) {
this.index = index;
this.direction = direction;
}
}
//这是描述一个访问磁道任务的一个类
class MyRunnable implements Runnable {
//要访问的磁道
public int track;
public boolean key = true;
public MyRunnable(int track) {
this.track = track;
}
@Override
public void run() {
System.out.print(track + " ");
}
}
public class DiskScheduling extends Thread {
//需要一个链表去存储去存储要访问磁盘的线程
//一个count记录访问次数
//sum去记录访问距离
//还需要一个磁头
//还需要一个最大磁道是多少
private List<MyRunnable> threadList = new LinkedList<>();
private int count;
private int sum;
private Head head;
public static final int MaximumTrack = 200;
//在构造函数里初始化磁头
public DiskScheduling(int index, String direction) {
this.head = new Head(index, direction);
}
//需要一个方法往链表为添加程序
public void add(int[] tracks) throws InterruptedException {
//创建线程 线程的名字就是他有寻找的磁道地址
for (int track : tracks
) {
MyRunnable myRunnable = new MyRunnable(track);
threadList.add(myRunnable);
}
//将链表按要寻道的地址进行排序
threadList.sort(new Comparator<MyRunnable>() {
@Override
public int compare(MyRunnable o1, MyRunnable o2) {
return o1.track - o2.track;
}
});
this.start();
this.join();
//worke();
}
@Override
public void run() {
while (this.count != threadList.size()) {
while (this.head.direction.equals("right")) {
for (MyRunnable m : threadList
) {
if (m.track >= head.index && m.key) {
count++;
int distance = m.track - this.head.index;
sum += distance;
this.head.index = m.track;
m.key = false;
m.run();
//threadList.remove(m);
}
this.head.direction = "left";
}
}
while (this.head.direction.equals("left")) {
for (int i = threadList.size() - 1; i >= 0; i--) {
if (threadList.get(i).track > this.head.index || !threadList.get(i).key) {
continue;
}
//此时表示找到了比现在下标小的
this.count++;
int distance = this.head.index - threadList.get(i).track;
sum += distance;
this.head.index = threadList.get(i).track;
threadList.get(i).key = false;
this.threadList.get(i).run();
//this.threadList.remove(this.threadList.get(i));
}
this.head.direction = "right";
}
}
}
/* //需要一个方法去执行程序
private void worke() throws InterruptedException {
while (! this.threadList.isEmpty()) {
while (this.head.direction.equals("right")) {
synchronized (this) {
for (Thread t : this.threadList
) {
if (Integer.parseInt(t.getName()) > this.head.index) {
this.count++;
int distance = Integer.parseInt(t.getName()) - this.head.index;
sum += distance;
this.head.index = Integer.parseInt(t.getName());
t.start();
t.join();
this.threadList.remove(t);
}
}
}
this.head.direction = "left";
}
while (this.head.direction.equals("left")) {
synchronized (this) {
for (int i = this.threadList.size() - 1; i >= 0; i--) {
if (Integer.parseInt(this.threadList.get(i).getName()) > this.head.index) {
continue;
}
//此时表示找到了比现在下标小的
this.count++;
int distance = this.head.index - Integer.parseInt(this.threadList.get(i).getName());
sum += distance;
this.head.index = Integer.parseInt(this.threadList.get(i).getName());
this.threadList.get(i).start();
this.threadList.get(i).join();
this.threadList.remove(this.threadList.get(i));
}
}
this.head.direction = "right";
}
}
}*/
//需要一个方法返回平均寻道长度
public float averageSeekLength () {
return (float) ((this.sum * 1.0) / this.count);
}
}
- 测试
假设磁盘有200个磁道,用C语言随机函数随机生成一个磁道请求序列(不少于15个)放入模拟的磁盘请求队列中,假定当前磁头在100号磁道上,并向磁道号增加的方向上移动。请给出按电梯调度算法进行磁盘调度时满足请求的次序,并计算出它们的平均寻道长度。
import java.util.Arrays;
import java.util.Random;
public class DiskTest {
public static void main(String[] args) throws InterruptedException {
//需要在创建磁盘调度的时候说明此时磁头的位置和方向
DiskScheduling diskScheduling = new DiskScheduling(100, "right");
//生成15个随机数
int[] nums = new int[15];
for (int i = 0; i < 15; i++) {
Random random = new Random();
nums[i] = random.nextInt(DiskScheduling.MaximumTrack);
}
System.out.println("初始申请序列:");
System.out.println(Arrays.toString(nums));
System.out.println("=========================");
System.out.println("电梯调度执行顺序");
diskScheduling.add(nums);
System.out.println();
//等线程执行完毕再去打印寻道
diskScheduling.join();
System.out.print("平均寻道为:");
System.out.println(diskScheduling.averageSeekLength());
}
}
- 结果