写在前面

欢迎讨论。


问题描述

用JAVA同步方法实现磁头引臂调度问题,采用SCAN算法。
要求:(1) 给出核心调度解法,用JAVA类实现,其中包含require(dest)和release()两个同步方法;(2) 创建若干线程或进程,分别提出某一磁道上某个磁盘块的访问请求,给出调度结果。
说明:(1)假定盘面上共有200个磁道,由外向内依次编号0,…,199,盘面只有一个移动磁头; (2)模拟访问磁盘时打印出磁道编号,并延迟一段时间以表示磁盘I/O操作时间;


Java实现

Device用于模拟向磁盘申请访问的设备,向磁盘提出申请访问请求
Disk用于模拟磁盘,scan方法在其中实现
Main启动线程


Device

/*** @Description 用于模拟向磁盘申请访问的设备*/
public class Device implements Runnable {Disk disk;public Device(Disk disk) {this.disk = disk;}@Overridepublic void run() {while (disk.getTimes()>0){int max=199,min=0;int randomDest = (int) (Math.random()*(max-min)+min);disk.require(randomDest);//申请磁道try {Thread.sleep(1500);//运行一段时间后再次申请} catch (InterruptedException e) {e.printStackTrace();}}}
}

Disk

/*** @Description 此类用于模拟磁盘*/
public class Disk implements Runnable {int[]dests;//磁道int position;//当前位置int flag;//移动方向,1下标增大,-1下标减小int times;public synchronized int getTimes() {return times;}public Disk(int position, int flag) {this.position = position;this.flag = flag;dests=new int[200];times=10;System.out.println("磁头引臂当前磁道:"+position+" 移动方向:"+flag);}@Overridepublic void run() {//等待设备启动和申请try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}//开始检查设备的申请并提供访问服务boolean result=false;while (times>0){//为了使程序停止,设定可访问次数try {result=manage();//分配磁道,访问磁道} catch (InterruptedException e) {e.printStackTrace();}if (result){times--;}}System.out.println("结束全部访问...");}/*** @Description 用于模拟磁道的调度* @return 进行了一次传输返回true,无传输返回false* @throws InterruptedException*/private synchronized boolean manage() throws InterruptedException {int nextDest= scan();//利用scan找到下一个应该访问的磁道if(nextDest!=-1){using(nextDest);//移动磁头引臂访问磁道release();//释放return true;}else{//System.out.println("无人访问,磁盘暂时休息...");return false;}}/*** @Description 外部设备(cpu等)申请访问的磁道编号* @param dest 申请访问的磁道编号*/void require(int dest){System.out.println("申请了磁道:"+dest);dests[dest]++;}/*** @Description 采用scan算法计算引臂应移动到的位置* @return 有磁道被申请访问时,返回磁道编号,没有时返回-1*/private int scan(){int next=-1;next=hasNext();if (next!=-1){//当前方有磁道被申请return next;}else{//前方无磁道被申请,查看反向flag=-flag;next=hasNext();if(next!=-1){//反向上有磁道被申请return next;}}return -1;}/*** @Description 模拟磁盘被使用* @param dest 申请访问的磁道编号* @throws InterruptedException*/private synchronized void using(int dest) throws InterruptedException {int d=Math.abs(position-dest);position=dest;System.out.println("正在访问磁道:"+dest+" (移动了"+d+"个磁道)");//模拟访问过程try {Thread.sleep(1000);}catch (Exception e){}return;}/*** @Description 用于磁道的释放*/private synchronized void release(){dests[position]--;System.out.println("释放了磁道:"+position);}/*** @return 引臂移动方向上有磁道被申请,返回最近的磁道编号,无磁道被申请,返回-1*/private int hasNext(){for(int i=position;i<dests.length&&i>0;i+=flag){if(dests[i]>0){return i;}}return -1;}
}

Main

public class Main {public static void main(String[] args) {int threadNumber=6;//线程数int deviceNumber=threadNumber-1;//可能申请磁盘的设备数//磁盘、设备、线程Disk disk=new Disk(100,-1);Thread[]threads=new Thread[threadNumber];Device[]devices=new Device[deviceNumber];threads[0]=new Thread(disk,Integer.toString(0));for (int i=1;i<threadNumber;i++){devices[i-1]=new Device(disk);threads[i]=new Thread(devices[i-1],Integer.toString(i));}//启动线程for (int i=0;i<threadNumber;i++){threads[i].start();}}
}

进阶-双引臂SCAN调度问题

仍假定盘面上共有200个磁道,由外向内依次编号0,…,199,同一引臂上两个磁头head1和head2,二者相距100个磁道,复位时head1位于磁道0,head2位于磁道100,head1负责0…99磁道上的I/O请求,head2负责100…199磁道上的I/O请求。例如,当head1位于磁道35时,head2位于磁道135。
仅需对部分函数修改。


hasNext()函数的修改

/*** @return 引臂移动方向上有磁道被申请,返回最近的磁道编号,无磁道被申请,返回-1*/private int hasNext(){int head1;//第一个磁头int head2;//第二个磁头if(position<dests.length/2){head1=position;head2=position+(dests.length/2);}else{head1=position-(dests.length/2);head2=position;}//System.out.println(head1+" "+head2);for(;head2<dests.length&&head1>=0;head1+=flag,head2+=flag){if(dests[head1]>0){return head1;}else if (dests[head2]>0){return head2;}}return -1;}

using()函数的修改

/*** @Description 模拟磁盘被使用* @param dest 申请访问的磁道编号* @throws InterruptedException*/private synchronized void using(int dest) throws InterruptedException {int d=0;if((dest-(dests.length/2))*(position-(dests.length/2))<0){//说明要访问的磁道与上次访问的位置不在一侧if(dest>(dests.length/2)){//上次访问的位置在0-99position=position+(dests.length/2);}else{//上次访问的位置在100-199.这次需要访问的位置在0-99position=position-(dests.length/2);}}d=Math.abs(position-dest);position=dest;System.out.println("正在访问磁道:"+dest+" (移动了"+d+"个磁道)");//模拟访问过程try {Thread.sleep(1000);}catch (Exception e){}return;}

不足

代码中磁头和磁盘耦合度过高。
解决办法可以是磁头可以抽象出类来或者磁头用数组保存磁头的移动可以单独设计成函数。

SCAN算法 | 磁头引臂调度问题 | 双磁头进阶 | Java实现(详细注释)相关推荐

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

    操作系统--磁头引臂调度SCAN算法 JAVA实现--双磁头引臂 具体要求 代码~ 说明 重要说明 具体要求 代码~ package com.guangluo.OS;import java.util. ...

  2. 数学建模常用算法:蚁群算法求解tsp问题+att48算例测试【java实现--详细注释】

    代码 蚂蚁类 package com.dam.heuristic.aco.test;import java.util.*;public class Ant {//蚂蚁所走的城市序列private Li ...

  3. 汽车加油问题 贪心算法 Java(详细注释)

    目录 一.问题描述 二.分析过程 三.参考代码及运行结果 一.问题描述 二.分析过程 i :第i个加油站 i = 0:出发地 i = k:目的地(共 k+1 个站,由问题知,k = 5) x[i] : ...

  4. 数学建模常用算法:粒子群算法(PSO)求解二元函数最小值+限定x,y范围测试【java实现--详细注释+Matlab绘制粒子群飞行过程】

    代码 package com.dam.heuristic.pso.test;import java.util.List; import java.util.Random;public class Ps ...

  5. 蚁群算法解决TSP问题(2#JAVA代码+详细注释+对比动态规划【JAVA】)

    第一部分:原理 TSP10cities.txt 1 2066 2333 2 935 1304 3 1270 200 4 1389 700 5 984 2810 6 2253 478 7 949 302 ...

  6. 基于蚁群算法的中国34个主要城市TSP问题(详细注释)

    城市经纬度数据 北京 ;116.46;39.92 天津 ;117.2;39.13 上海 ;121.48;31.22 重庆 ;106.54;29.59 拉萨 ;91.11;29.97 乌鲁木齐 ;87. ...

  7. 计算几何入门 1.6:凸包的构造——Graham Scan算法

    上文简要分析出了凸包构造问题算法的下界:O(nlogn),在此就引入一种下界意义上最优的算法:Graham Scan算法.这种算法可以保证在最坏情况下时间复杂度也不超过nlogn.我们先大致了解一下算 ...

  8. 凸包Graham Scan算法实现

    凸包Graham Scan算法实现 凸包算法实现点集合中搜索凸包顶点的功能,可以处理共线情况,可以输出共线点也可以不输出而只输出凸包顶点.经典的Graham Scan算法,点排序使用极角排序方式,并对 ...

  9. Tarjan算法求解桥和边双连通分量(附POJ 3352 Road Construction解题报告)

    http://blog.csdn.net/geniusluzh/article/details/6619575 在说Tarjan算法解决桥和边双连通分量问题之前我们先来回顾一下Tarjan算法是如何求 ...

最新文章

  1. The method replace(int, Fragment) in the type FragmentTransaction is not applicable for the argument
  2. 用JavaScript获取一个超链接的绝对URL地址
  3. 不要过高估计SDN的能力,也善于发现SDN技术的缺陷之美
  4. 打印swift 变量的类型
  5. 【转】电驴提示“该内容尚未提供权利证明,无法提供下载”之解决办法详解...
  6. ACM-ICPC 2017 Asia Nanning
  7. java intern_java String的intern方法
  8. 移除apt源_apt提示处理归档 (--unpack)时出错的解决办法
  9. angularjs 表单校验指令_angular4.0的模板式表单、响应式表单及其错误提示
  10. 微信小程序开发笔记2——如何发布小程序体验版
  11. solr java score_java-Apache Solr:按位运算来过滤搜索结果
  12. 转liunx 常用命令
  13. 微星主板黑苹果_AMD黑苹果主机金牌装机单
  14. Smart3D系列教程
  15. fastreport oracle,如何从FastReport .NET报表设计器连接到OracleDB数据库
  16. DDR核心频率、工作频率,等效频率详解
  17. Pigeon 工具类ExtensionLoader
  18. missing separator 解决方法
  19. 159.Vue实现个人博客(七)【Vue2.0-路由参数】 2019.03.15
  20. android studio hiera,PL/SQL初学者必读:几十个实用的PL/SQL

热门文章

  1. [Unity好插件之PlayMaker]PlayMaker如何扩展额外创建更多的脚本
  2. GitKraken使用教程
  3. matlab四维图形,matlab绘四维图
  4. 北京开放大学非凡十年,谱写首都开放教育新篇章
  5. java毕业设计的电影社区网站mybatis+源码+调试部署+系统+数据库+lw
  6. 【原创】2021-02嵌入式月刊:登陆火星的F prime飞行软件框架
  7. xser php framework v0.1正式版 -- 发布
  8. 1251 Colombian Number
  9. 微信小程序开发——第一个小程序
  10. 百分比转换成十六进制