精华内容
下载资源
问答
  • java解决操作系统中的磁盘调度算法,包括了先来先服务法,最短寻到优先法以及电梯算法
  • 实用标准文案 目录 目录 1 1 课程设计目的 1 1.1 编写目的 1 2 课程设计内容 1 2.1 设计...1.1 编写目的 本课程设计的目的是通过磁盘调度算法设计一个磁盘调度模拟系统 从而使磁盘调度算法更加形象化容易使人理解使磁
  • 磁盘调度算法java实现

    热门讨论 2013-05-30 20:54:38
    随机生成磁盘序列 用java实现了FIFO、SSTF、SCAN和C-SCAN算法模拟磁盘调度 有用户界面,有序列结果记录,有计算移动磁道数
  • 在操作系统课上的一点小感想,基于JAVA磁盘调度算法,分享出来和大家一起学习。 先来先服务(FCFS)算法。即先来的请求先被响应。FCFS策略为我们建立起一个随机访问机制的模型,但是假如用这个策略反复响应从里到...

    在操作系统课上的一点小感想,基于JAVA的磁盘调度算法,分享出来和大家一起学习。

    先来先服务(FCFS)算法。即先来的请求先被响应。FCFS策略为我们建立起一个随机访问机制的模型,但是假如用这个策略反复响应从里到外的请求,那么将会消耗大量的时间。FCFS也被看作是最简单的磁盘调度算法。

    最短寻道时间优先(SSTF)算法。要求访问的磁道,与当前磁头所在的磁道距离最近,以使每次的寻道时间最短。

    扫描调度(SCAN)算法。该算法不仅考虑到欲访问的磁道与当前磁道间的距离,更优先考虑的是磁头当前的移动方向。例如,当磁头正在自里向外移动时,SCAN算法所考虑的下一个访问对象,应是其欲访问的磁道,既在当前磁道之外,又是距离最近的。这样自里向外的访问,直至再无更外的磁道需要访问时,才将磁道换向自外向里移动。这时,同样也是每次选择这样的进程来调度,也就是要访问的当前位置内距离最近者,这样,磁头又逐步地从外向里移动,直至再无更里面的磁道要访问,从而避免了出现“饥饿”现像。

    循环扫描(C-SCAN)算法。当磁头刚从里向外移动而越过了某一磁道时,恰好又有一进程请求访问此磁道,这时,该里程就必须等待,为了减少这种延迟,CSCAN算法规定磁头单向移动,而本实验过程中我们所设计的是磁头从里向外移动,而从外向里移动时只须改方向而已,本实验未实现。但本实验已完全能演示循环扫描的全过程。

    6607861-f6ffdfd6a8f903bd.png

    参考博文和源码下载地址:

    https://write-bug.com/article/1362.html

    展开全文
  • 磁盘调度算法的模拟与实现(java) 1、先来先服务(FCFS) 2、最短寻道时间优先(SSTF) 3、扫描算法(SCAN) 4、循环扫描算法(CSCAN)
  • 磁盘调度算法Java版(FCFS,SSTF,SCAN)
  • Java实现磁盘调度算法

    千次阅读 多人点赞 2017-01-22 18:14:18
    Java实现磁盘调度算法磁盘调度算法有很多种,包括先来先服务(FCFS)、最短寻道优先算法(SSTF)、扫描算法(SCAN)、循环扫描算法等(CSCAN)等等,各种算法的详细介绍在操作系统等书中有详细介绍。这里选取前三种调度算法...

    Java实现磁盘调度算法

    • 磁盘调度算法有很多种,包括先来先服务(FCFS)、最短寻道优先算法(SSTF)、扫描算法(SCAN)、循环扫描算法等(CSCAN)等等,各种算法的详细介绍在操作系统等书中有详细介绍。这里选取前三种调度算法进行实现,语言采用Java。
      三种算法的简介为:

      1、FCFS:按磁盘访问请求的到来顺序进行响应。如若有六个磁盘访问请求依次到来,六个请求所请求访问的磁道号为33,78,55,120,63,70;则根据FCFS,将按请求到来顺序进行调度响应,所以磁盘访问顺序为:33,78,55,120,63,70。

      2、SSTF:此算法优先选取欲访问的磁道距离当前磁头所在位置最近的请求进行调度。假设一组磁盘访问请求如上,并假设磁头初始时在磁道号为60的位置,则磁盘访问顺序为:63,70,78,55,33,120.

      3、SCAN:此算法在SSTF的基础上规定了磁头的运动方向,按磁头初始运动方向,选取此方向上欲访问磁道距离磁头所在位置最近的请求进行调度。切磁头只能继续向该方向行进,直至该方向所有请求均调度完毕。若一组磁道访问请求如上,磁头初始位置仍为60,并假设此时磁头运动方向为磁道号增大方向,则磁盘访问顺序变为:63,70,78,120,55,33.

      在进行编程实现时,磁盘访问请求所要访问的磁道号随机产生,产生的磁盘访问请求数量、磁道号的允许范围、磁头初始运动方向均有用户设定(在SACN算法运行时设定)。

      工程截图如下(IDE用的eclipse,jdk版本为1.8):
      这里写图片描述
      下面贴出代码:

    一、磁盘访问请求的封装。一个磁盘访问请求包括请求号,欲请求的磁道号,是否已被调度的标记。实际上一个请求可以看作是一个进程。

    package com.bean;
    
    public class Request {
    	private int id; //请求号,唯一标识一个请求
    	private int number; //欲访问的磁道号
    	private int flag; //是否已被调度的标记,初始为0,表示为被调度。
    	public Request(){ //空白构造器
    		this.id=0;
    		this.number=0;
    		this.flag=0;
    	}
    	public Request(int id,int num){ //带参构造器
    		this.id=id;
    		this.number=num;
    		this.flag=0;
    	}
    	public void setId(int id){
    		this.id=id;
    	}
    	
    	// 以下是一系列set和get方法
    	public int getId(){
    		return this.id;
    	}
    	
    	public void setNumber(int number){
    		this.number=number;
    	}
    	public int getNumber(){
    		return this.number;
    	}
    	
    	public void setFlag(int flag){
    		this.flag=flag;
    	}
    	public int getFlag(){
    		return this.flag;
    	}
    }
    
    

    二、作业类的封装。即模拟一个作业,其中有一个getRandomRequest()方法,在设定的磁道允许范围内,产生一个磁盘访问序列,也即一个request数组。欲产生的磁盘访问请求数量由用户运行时设定,每个访问请求的磁道号在设定的磁道允许范围内随机产生。

    package com.bean;
    
    import java.util.HashSet;
    import java.util.Random;
    import java.util.Set;
    
    public class Work {
    	private int start; //允许访问的磁道号范围的起始磁道号
    	private int end; //允许访问的磁道号范围的终止磁道号
    	// 即请求可请求访问的磁道号在start与end之间
    	private int num; //所要产生的磁盘访问请求数量
    	public Work(){ //不带参构造器
    		this.start=0;
    		this.end=0;
    		this.num=0;
    	}
    	public Work(int start,int end,int num){ //带参构造器
    		this.start=start;
    		this.end=end;
    		this.num=num;
    	}
    	public int getStart(){
    		return this.start;
    	}
    	public int getEnd(){
    		return this.end;
    	}
    	
    	public Request[] getRandomRequest(){ //产生磁盘访问请求的方法
    		Request req[]=new Request[num]; //数组声明num个请求
    		Random random=new Random();
    		Set<Integer> set=new HashSet<Integer>();
    		while(true){ //为num个请求依次生成要访问的磁道号,放入set集合
    			set.add((int)(random.nextInt(end-start)+start));
    			if(set.size()==num)
    				break;
    		}
    		int i=0;
    		//将set集合中的数取出依次付给各请求。使用set的目的是让num个访问请求要访问的磁道号各不同。
    		for(int temp:set){
    			req[i]=new Request(i+1,temp);
    			i++;
    		}
    		return req;
    	}
    }
    

    三、调度算法的实现。三个方法对应三个调度算法。

    package com.diaodu;
    
    import java.text.DecimalFormat;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.Scanner;
    import java.util.TreeSet;
    
    import com.bean.Request;
    import com.bean.Work;
    
    public class DiaoDu {
    	Work work;
    	Request[] request;
    	int begin;//磁头初始位置
    	DecimalFormat df = new DecimalFormat("0.000");
    	public DiaoDu(Work work){//构造器,接收一个作业
    		this.work=work;
    		request=work.getRandomRequest();
    		//磁头初始位置设为所允许访问磁道号范围的中间值。
    		//如若磁道访问允许范围为100~300,则磁头初始位置在200处。
    		begin=(work.getStart()+work.getEnd())/2;
    	}
    	
    	public void FCFS(){//先来先服务算法
    		begin=(work.getStart()+work.getEnd())/2;
    		Request[] req=request;
    		System.out.println("磁道号区间:"+work.getStart()+"到"+work.getEnd());
    		System.out.println("磁头初始时所在磁道号:"+begin);
    		
    		double sum=0;
    		System.out.println("请求号        被访问的下一个磁道号               移动距离");
    		for(Request r:req){						
    			System.out.println("--"+r.getId()+"----------------"+r.getNumber()+"-----------------"+Math.abs(begin-r.getNumber())+"--");
    			sum+=Math.abs(begin-r.getNumber());
    			begin=r.getNumber();
    		}
    		System.out.println("***********平均寻道长度为:"+df.format(sum/req.length)+"************");
    	}
    	
    	
    	public void SSTF(){//最短寻道优先
    		begin=(work.getStart()+work.getEnd())/2;
    		Request[] req=request;
    		System.out.println("磁道号区间:"+work.getStart()+"到"+work.getEnd());
    		System.out.println("磁头初始时所在磁道号:"+begin);
    		
    		int t=0;
    		double sum=0;
    		System.out.println("请求号        被访问的下一个磁道号               移动距离");
    		for(int i=0;i<req.length;i++){
    			int temp=work.getEnd();
    			for(int j=0;j<req.length;j++){
    				if(Math.abs(req[j].getNumber()-begin)<temp&&req[j].getFlag()==0){
    					temp=Math.abs(req[j].getNumber()-begin);					
    					t=j;
    				}
    			}			
    			System.out.println("--"+req[t].getId()+"----------------"+req[t].getNumber()+"-----------------"+temp+"--");
    			begin=req[t].getNumber();
    			req[t].setFlag(1);
    			sum+=temp;
    		}
    		System.out.println("***********平均寻道长度为:"+df.format(sum/req.length)+"***********");
    	}
    	
    	
    	
    	public void SCAN(){//扫描算法
    		begin=(work.getStart()+work.getEnd())/2;
    		Request[] req=request;
    		int direction;//磁头运动方向方向
    		System.out.println("设定磁头初始化运动方向(1:磁道号增大方向    -1:磁道号减小方向):");
    		direction=new Scanner(System.in).nextInt();
    		System.out.println("磁道号区间:"+work.getStart()+"到"+work.getEnd());
    		System.out.println("磁头初始时所在磁道号:"+begin);
    		if(direction==1)
    			System.out.println("磁头初始运动方向: 磁道号增大方向");
    		else
    			System.out.println("磁头初始运动方向: 磁道号减小方向");
    		
    		Map<Integer,Request> map=new HashMap<Integer,Request>();
    		TreeSet<Integer> ts1=new TreeSet<Integer>();
    		TreeSet<Integer> ts2=new TreeSet<Integer>();
    		for(Request r:req){
    			if(r.getNumber()>=begin){
    				map.put(r.getNumber(), r);
    				ts1.add(r.getNumber());
    			}
    			else{
    				map.put(r.getNumber(), r);
    				ts2.add(r.getNumber());
    			}
    		}		
    		
    		
    		System.out.println("请求号        被访问的下一个磁道号               移动距离");
    		double sum=0;
    		if(direction==1){
    
    			for(int temp:ts1){
    				System.out.println("--"+map.get(temp).getId()+"----------------"+temp+"-----------------"+Math.abs(temp-begin));
    				sum+=Math.abs(temp-begin);
    				begin=temp;
    			}
    			for(int temp:ts2.descendingSet()){
    				System.out.println("--"+map.get(temp).getId()+"----------------"+temp+"-----------------"+Math.abs(temp-begin));
    				sum+=Math.abs(temp-begin);
    				begin=temp;
    			}
    			
    		}
    		
    		else{
    			for(int temp:ts2.descendingSet()){
    				System.out.println("--"+map.get(temp).getId()+"----------------"+temp+"-----------------"+Math.abs(temp-begin));
    				sum+=Math.abs(temp-begin);
    				begin=temp;
    			}
    			for(int temp:ts1){
    				System.out.println("--"+map.get(temp).getId()+"----------------"+temp+"-----------------"+Math.abs(temp-begin));
    				sum+=Math.abs(temp-begin);
    				begin=temp;
    			}
    		}
    		System.out.println("***********平均寻道长度为:"+df.format(sum/req.length)+"***********");
    	}
    }
    
    

    四、场景类测试。在main方法中定义相关对象,进行测试。

    package com.client;
    import java.util.Scanner;
    
    import com.bean.Work;
    import com.diaodu.DiaoDu;
    
    public class Client {
    
    	public static void main(String[] args) {
    		// TODO Auto-generated method stub
    		int start,end,num;
    		Scanner in=new Scanner(System.in);
    		System.out.println("设定磁道起止道号:");
    		System.out.print("起始道号:");
    		start=in.nextInt();
    		System.out.print("终止道号:");
    		end=in.nextInt();
    		System.out.print("输入磁盘访问的请求数:");
    		num=in.nextInt();
    		
    		Work work=new Work(start,end,num);
    		DiaoDu diaodu=new DiaoDu(work);
    		
    		System.out.println();
    		System.out.println("*************先来先服务调度法*************");
    		diaodu.FCFS();
    		
    		System.out.println();
    		System.out.println("***********最短寻道时间优先调度法************");
    		diaodu.SSTF();
    		
    		System.out.println();
    		System.out.println("****************扫描调度法*****************");
    		diaodu.SCAN();
    	}
    
    }
    
    

    五、运行实例截图如下:
    这里写图片描述
    这里写图片描述

    展开全文
  • 1.支持算法:FCFS、SSTF、SCAN、CSCAN 2.用java实现,图形界面
  • 使用Java实现操作系统中移动臂磁盘调度算法,包括先来先服务调度算法、最短寻找时间优先调度算法、电梯调度算法、单向扫描和双向扫描调度算法,有简单的图形用户界面
  • 磁盘调度算法主要包括三种算法:先来先服务、最短寻道,电梯调度。程序为java代码,编写,调试,运行都在myeclipse环境下完成,欢迎下载!
  • 模拟磁盘调度算法SCAN

    2017-06-01 15:19:29
    模拟磁盘调度算法SCAN实验报告,含代码和运行结果等等
  • 复习模拟实现一种磁盘调度算法(FCFS、SSTF、Scan、CScan、2-step Scan任选一),进一步加深对磁盘调度效率的理解。本实验模拟实现了电梯扫描算法
  • 使用Java实现操作系统中移动臂磁盘调度算法,包括先来先服务调度算法、最短寻找时间优先调度算法、电梯调度算法、单向扫描和双向扫描调度算法,有简单的图形用户界面和通过线程动态显示
  • java写的磁盘调度算法程序,用netbeans写成,是本人的计算机操作系统的课程设计,里面附带有详细的报告,有用的下吧,可以很容易改成C#的。
  • 操作系统,用java实现磁盘调度算法,有swing界面,包括算法fcfs, sstf, scan,cscan。
  • 磁盘调度算法 图形界面 java实现 包含几种调度算法 内无错误
  • FCFS实现磁盘调度算法

    2020-06-03 09:29:17
    FCFS算法根据进程请求访问磁盘的先后顺序进行调度,这是一种最简单的调度算法。该算法的优点是具有公平性。如果只有少量进程需要访问,且大部分请求都是访问簇聚的...所以,实际磁盘调度中考虑一些更为复杂的调度算法
  • java实现的四种磁盘调度算法:fcfs sstf scan cscan 。 可以随机生产磁道号,也可以自己指定。然后用表格的形式呈现出四种算法的磁道访问序列。欢迎下载。
  • 简单的磁盘移臂调度算法,FCFS,SSTF,Scan和电梯算法 有简单的界面显示 用的java语言
  • 磁盘调度算法

    2017-03-01 17:20:01
    大家支持下,原创
  • 实验六 磁盘调度算法 1 实验目的 通过这次实验加深对磁盘调度算法的理解进一步掌握先来先 服务 FCFS最 短寻道时间优先 SSTFSCAN和循环 SCAN算法 的实现方法 2 试验内容 问题描述 设计程序模拟先来先服务 FCFS最短...
  • 磁盘调度算法sstf算法 辅助存储和磁盘调度算法 (Secondary Storage and Disk Scheduling Algorithms) Secondary storage devices are those devices whose memory is non volatile, meaning, the stored data will ...

    磁盘调度算法sstf算法

    Secondary storage devices are those devices whose memory is non volatile, meaning, the stored data will be intact even if the system is turned off. Here are a few things worth noting about secondary storage.

    辅助存储设备是那些内存是非易失性的设备,这意味着即使关闭系统电源,存储的数据也将保持完整。 以下是有关辅助存储的一些注意事项。

    • Secondary storage is also called auxiliary storage.

      辅助存储也称为辅助存储。

    • Secondary storage is less expensive when compared to primary memory like RAMs.

      与主存储器(如RAM)相比,二级存储的价格便宜。

    • The speed of the secondary storage is also lesser than that of primary storage.

      辅助存储的速度也小于主存储的速度。

    • Hence, the data which is less frequently accessed is kept in the secondary storage.

      因此,较少访问的数据被保存在辅助存储器中。

    • A few examples are magnetic disks, magnetic tapes, removable thumb drives etc.

      一些示例是磁盘,磁带,可移动拇指驱动器等。

    磁盘结构 (Magnetic Disk Structure)

    In modern computers, most of the secondary storage is in the form of magnetic disks. Hence, knowing the structure of a magnetic disk is necessary to understand how the data in the disk is accessed by the computer.

    在现代计算机中,大多数辅助存储都是磁盘形式的。 因此,必须了解磁盘的结构才能理解计算机如何访问磁盘中的数据。

    Magnetic Disk

    Structure of a magnetic disk

    磁盘的结构

    A magnetic disk contains several platters. Each platter is divided into circular shaped tracks. The length of the tracks near the centre is less than the length of the tracks farther from the centre. Each track is further divided into sectors, as shown in the figure.

    磁盘包含多个磁盘 。 每个盘子分成圆形的轨道 。 靠近中心的轨道的长度小于远离中心的轨道的长度。 如图所示,每个磁道进一步划分为多个扇区

    Tracks of the same distance from centre form a cylinder. A read-write head is used to read data from a sector of the magnetic disk.

    距中心相同距离的轨道形成一个圆柱体。 读写头用于从磁盘的扇区读取数据。

    The speed of the disk is measured as two parts:

    磁盘的速度分为两个部分:

    • Transfer rate: This is the rate at which the data moves from disk to the computer.

      传输速率:这是数据从磁盘移动到计算机的速率。

    • Random access time: It is the sum of the seek time and rotational latency.

      随机访问时间:它是寻道时间和旋转等待时间的总和。

    Seek time is the time taken by the arm to move to the required track. Rotational latency is defined as the time taken by the arm to reach the required sector in the track.

    搜索时间是手臂移动到所需轨道所花费的时间。 旋转等待时间定义为手臂到达轨道中所需扇区所花费的时间。

    Even though the disk is arranged as sectors and tracks physically, the data is logically arranged and addressed as an array of blocks of fixed size. The size of a block can be 512 or 1024 bytes. Each logical block is mapped with a sector on the disk, sequentially. In this way, each sector in the disk will have a logical address.

    即使磁盘按扇区排列并在物理上进行跟踪,但数据在逻辑上按固定大小的块阵列排列和寻址。 块的大小可以是5121024字节。 每个逻辑块依次与磁盘上的一个扇区映射。 这样,磁盘中的每个扇区都会有一个逻辑地址。

    磁盘调度算法 (Disk Scheduling Algorithms)

    On a typical multiprogramming system, there will usually be multiple disk access requests at any point of time. So those requests must be scheduled to achieve good efficiency. Disk scheduling is similar to process scheduling. Some of the disk scheduling algorithms are described below.

    在典型的多程序系统上,通常在任何时间点都会有多个磁盘访问请求。 因此,必须安排这些请求以实现良好的效率。 磁盘调度类似于进程调度。 下面描述了一些磁盘调度算法。

    先到先得 (First Come First Serve)

    This algorithm performs requests in the same order asked by the system. Let's take an example where the queue has the following requests with cylinder numbers as follows:

    该算法以系统要求的相同顺序执行请求。 让我们以一个示例为例,其中队列具有以下带有柱面编号的请求,如下所示:

    98, 183, 37, 122, 14, 124, 65, 67

    98、183、37、122、14、124、65、67

    Assume the head is initially at cylinder 56. The head moves in the given order in the queue i.e., 56→98→183→...→67.

    假设头部最初在汽缸56处 。 磁头在队列中以给定的顺序移动,即56→98→183→...→67

    First Come First Serve

    最短搜寻时间优先(SSTF) (Shortest Seek Time First (SSTF))

    Here the position which is closest to the current head position is chosen first. Consider the previous example where disk queue looks like,

    在此首先选择最接近当前磁头位置的位置。 考虑前面的示例,其中磁盘队列如下所示:

    98, 183, 37, 122, 14, 124, 65, 67

    98、183、37、122、14、124、65、67

    Assume the head is initially at cylinder 56. The next closest cylinder to 56 is 65, and then the next nearest one is 67, then 37, 14, so on.

    假设头部最初在汽缸56处 。 下一个最接近的气缸5665,然后下一个最近的一个是67,然后37,14,等等。

    Shortest Seek Time First

    扫描算法 (SCAN algorithm)

    This algorithm is also called the elevator algorithm because of it's behavior. Here, first the head moves in a direction (say backward) and covers all the requests in the path. Then it moves in the opposite direction and covers the remaining requests in the path. This behavior is similar to that of an elevator. Let's take the previous example,

    由于其行为,该算法也称为提升算法。 在这里,首先头部朝一个方向移动(例如向后移动)并覆盖路径中的所有请求。 然后,它沿相反的方向移动,并覆盖路径中的其余请求。 此行为类似于电梯的行为。 让我们来看前面的例子,

    98, 183, 37, 122, 14, 124, 65, 67

    98、183、37、122、14、124、65、67

    Assume the head is initially at cylinder 56. The head moves in backward direction and accesses 37 and 14. Then it goes in the opposite direction and accesses the cylinders as they come in the path.

    假设头部最初在汽缸56处 。 头部向后移动并进入3714 。 然后,它沿着相反的方向前进,并在圆柱体进入路径时进入圆柱体。

    SCAN algorithm

    翻译自: https://www.studytonight.com/operating-system/secondary-storage

    磁盘调度算法sstf算法

    展开全文
  • 磁盘调度管理代码实现(JAVA实现)

    万次阅读 2019-07-06 08:47:03
    通过编程实现不同磁盘调度算法。具体要求如下: 1.设定开始磁道号寻道范围,依据起始扫描磁道号和最大磁道号数,随机产生要进行寻道的磁道号序列。(也可以输入一组作业的磁道请求序列)2. 选择磁盘调度算法,显示该...

    1 设计内容

    2 分析设计
    2.1 算法原理
    通过编程实现不同磁盘调度算法。具体要求如下:

    1.设定开始磁道号寻道范围,依据起始扫描磁道号和最大磁道号数,随机产生要进行寻道的磁道号序列。(也可以输入一组作业的磁道请求序列)2. 选择磁盘调度算法,显示该算法的磁道访问顺序,计算出移动的磁道总数和平均寻道总数。并输出按选择的算法执行时的磁头移动轨迹。请在以下算法中任意选择两种实现,并对算法性能进行分析对比。
    实现提示:
    常用的磁盘调度算法简介如下:

    1.最短寻道优先算法SSTF:该算法选择这样的进程:其要求访问的磁道与当前磁头所在的磁道距离最近,以使每次的寻道时间最短。

    2.扫描算法SCAN:首先考虑磁盘请求的磁头移动方向,在方向一致的情况下优先调度与磁头最近的请求。若从内向外扫描,则在到达最外层柱面后,再改变方向从外向内扫描,达到最内层柱面后再重复前面过程;若从外向内扫描,则也在达到最内层后再改变方向。

    3.电梯算法: 电梯算法是对扫描算法的一种改进,基本思想是:没有访问请求时磁头不动,有访问请求时磁头来回扫描,每次选择磁头移动方向上离当前磁头位置最近的访问请求进行处理。扫描过程中,若磁头移动方向上仍有访问请求,则继续向同一个方向扫描;若磁头移动方向上不存在访问请求,则改变方向扫描。

    4.循环扫描算法CSCAN:CSCAN算法规定磁头单向移动,例如,只是自里向外移动,当磁头移到最外的磁道并访问后,磁头立即返回到最里的欲访问的磁道,亦即将最小磁道号紧接着最大磁道号构成循环,进行循环扫描。
    说明:测试数据可以先用教材上例题、习题中的数据,再使用随机数进行测试。

    2.2 程序结构
    我的这个程序也是用java来实现的,主要是采用了一个switch分支模块,分别有5个分支,前面四个分别对应四个调度算法FCFS、SSTF、SCAN、CSCAN,最后一个分支是提示错误的分支,比如输入的数字不是1-5,分支之前一个if语句如果用户选择5就退出程序。

    2.3 数据结构
    在这里插入图片描述

    2.4 程序流程图
    在这里插入图片描述
    2.5 关键代码

    2.5.1 FCFS关键代码

    /**
    	 * 先来先服务算法
    	 * @param cidao 要访问的磁道数组
    	 * @param m
    	 */
    	void FCFS(int cidao[],int m)   //磁道号数组,个数为m 
    {
        int now = -1;     //当前磁道号
        int sum = 0;	 //总寻道长度
        int i;
        float ave=0.0f;   //平均寻道长度
    	System.out.println("磁盘请求序列为:");
        for( i=0;i<m;i++)   //按先来先服务的策略输出磁盘请求序列
        {
    		System.out.print(cidao[i]+"  ");
        }
    	System.out.println();
    	System.out.print("请输入当前的磁道号:");
    	Scanner input = new Scanner(System.in);
    	  now=input.nextInt();
        sum+=Math.abs(cidao[0]-now);//求当前输入磁道和第一要访问磁道的距离
    	System.out.println("磁盘扫描序列为:");
    	System.out.print( now);
        for( i=0;i<m;i++)   //输出磁盘扫描序列
        {
    		System.out.print( " --> " + cidao[i]);
        }
        for(i=0;i<m-1;i++)   //求平均寻道长度 
        {
            sum+=Math.abs(cidao[i+1]-cidao[i]);
            ave=(float)sum/m;
        }
    	System.out.println();
    	System.out.println("平均寻道长度:"+ave);
    }
    

    2.5.2 SSTF关键代码

    /**有三种情况:前提是先按升序排序好
    	 * 1、若当前磁道号大于请求序列中最大者,则直接由内向外依次给予各请求服务
    	 * 2、若当前磁道号小于请求序列中最小者,则直接由外向内依次给予各请求服务,与第一种同理
    	 * 3、若当前磁道号大于请求序列中最小者且小于最大者
    	 * 最短寻到时间优先算法
    	 * @param cidao 要访问的磁道数组
    	 * @param m
    	 */
    void SSTF(int cidao[],int m)
    {
       int k=1;                   //用于第三种情况找到当前磁道号在排序好序列的位置
       int now = -1,left = -1,right = -1;
       int i,j,sum=0;
     
       float ave = 0.0f;     //用来存平均寻道长度
       Arrays.sort(cidao); //调用快速排序算法升序处理
       System.out.println("排序后:"); 
       for (int n = 0; n < cidao.length; n++) {
    	System.out.print(cidao[n] + "  ");
    }
       System.out.println();
       System.out.print("请输入当前的磁道号:");
    	Scanner input =new Scanner(System.in);
    	now = input.nextInt(); 
    	                        //注:柱面的编号是从外到内从0开始编号的
       if(cidao[m-1]<=now)     // 第一种种情况:若当前磁道号大于请求序列中最大者,则直接由内向外依次给予各请求服务
       {                       //比如:排序后 55 66 72 88 93 100 若当前磁道大于100就直接从100开始予以各请求服务
    	  System.out.println("磁盘扫描序列为:");
    	  System.out.print(now);
          for(i=m-1;i>=0;i--)
          System.out.print(" --> " + cidao[i]);
          sum=now-cidao[0];  
       }
       
       if(cidao[0]>=now)      // 第二种情况:若当前磁道号小于请求序列中最小者,则直接由外向内依次给予各请求服务,与第一种同理
       {                   
    	  System.out.println("磁盘扫描序列为:");
    	  System.out.print(now);
          for(i=0;i<m;i++)
    	  System.out.print( " --> " + cidao[i]);
          sum=cidao[m-1]-now;
       }
       
       if(now>cidao[0]&&now<cidao[m-1])   //第三种情况:若当前磁道号大于请求序列中最小者且小于最大者
       {
    	   System.out.println("磁盘扫描序列为:");
    	   
           while(cidao[k]<now)        //确定当前磁道在已排的序列中的位置
    	   {
              k++;                   //k从1开始找
                                     //例如:55 66 72 88 93 100 若当前磁道号为90 直到找到93才会跳出循环,此时k=4
    	   }
           left=k-1;                   //表示此时位置的左边逻辑下标  
           right=k;                     //表示此时位置的右边逻辑下表
           
           
           System.out.print(now); 
           while((left>=0)&&(right<m))    //当前磁道在请求序列范围内
        	                      
    	   {    
              if((now-cidao[left])<=(cidao[right]-now))       //选择与当前磁道最近的请求给予服务,
    		  {                                     //例如90和88比较在和93比较看谁距离短就先给哪个服务
    			 System.out.print( " --> " + cidao[left]); //这是左边距离近的情况
                 sum+=now-cidao[left];
                 now=cidao[left];
                 left=left-1;
    		  }
              else
    		  {  //System.out.print(now);
    			 System.out.print( " --> " + cidao[right]);  //这是右边距离近的情况
                 sum+=cidao[right]-now;
                 now=cidao[right];
                 right=right+1;
    		  }
    	   }
           
           if(left==-1)   //磁头移动到序列的最小号,返回内侧扫描仍未扫描的磁道
    	   {
              for(j=right;j<m;j++)
    		  {
    			 System.out.print( "--> "+ cidao[j]);
    		  }
              sum+=cidao[m-1]-cidao[0];
    	   }
           else      //磁头移动到序列的最大号,返回外侧扫描仍未扫描的磁道
    	   {
              for(j=left;j>=0;j--)
    		  {
    			 System.out.print( "--> "+ cidao[j]);//例如55 66 72 88 93 100假设当前磁道90
    		  }                                      //则按前面的算法会有90-->88-->93-->100,此时到100时right+1=6跳出循环
              sum+=cidao[m-1]-cidao[0];              //来到了else这个分支,把磁头转到之前left的位置循环输出
    	   }                                         //那个sum直接等于最后一个减去第一个,因为他总是会扫描到最外侧的磁道号
       }                                             //和(100-72)+(72-66)+(66-55)= 100-55 = 45 是一样的
       
       ave=sum/(float)(m);
       System.out.println();
       System.out.println("平均寻道长度: "+ave);
    }
    
    

    2.5.3 SCAN关键代码

    /**
     * 这个算法和最短寻道差不多一样的,先排序,也有三种情况,但是多了一个选择移动臂的方向
     * 1、若当前磁道号大于请求序列中最大者,则直接由内向外依次给予各请求服务
     * 2、若当前磁道号小于请求序列中最小者,则直接由外向内依次给予各请求服务
     * 3、第三种情况:若当前磁道号大于请求序列中最小者且小于最大者
     * 扫描算法(电梯算法)
     * @param cidao  用来存磁道号
     * @param m
     */
    void SCAN(int cidao[],int m)    //先要给出当前磁道号和移动臂的移动方向
    {
       int k=1;
       int now,left = -1,right = -1 ,choice = -1 ;
       int i,j,sum=0;
       float ave = 0.0f;
       Arrays.sort(cidao);
    System.out.println("排序后:");
       
       for (int n = 0; n < cidao.length; n++) {
    	System.out.print(cidao[n] + "  ");
    }
       System.out.println();
        System.out.print("请输入当前的磁道号:");
    	Scanner input =new Scanner(System.in);
    	now = input.nextInt();
       if(cidao[m-1]<=now)    //第一种情况:若当前磁道号大于请求序列中最大者,则直接由内向外依次给予各请求服务
       {   
    	  System.out.println("磁盘扫描序列为:");
    	  System.out.print(now);
          for(i=m-1;i>=0;i--)
    	  System.out.print( " --> " + cidao[i]);
          sum=now-cidao[0];   //反正都要扫描到最外侧,直接减最小的那个得的距离和一个一个减在相加是等价的
       }
       if(cidao[0]>=now)     //第二种情况:若当前磁道号小于请求序列中最小者,则直接由外向内依次给予各请求服务
       {   
    	  System.out.println("磁盘扫描序列为:");
    	  System.out.print(now);
          for(i=0;i<m;i++)
          System.out.print(" --> " + cidao[i]);
          sum=cidao[m-1]-now;        //同理
       }
       if(now>cidao[0]&&now<cidao[m-1])   //第三种情况:若当前磁道号大于请求序列中最小者且小于最大者
       {
           while(cidao[k]<now) //和SSTF算法一样先找到当前寻道号的位置
    	   {
               k++;
    	   }
           left=k-1;
           right=k;
    	   System.out.println("请输入当前移动臂的移动的方向 (1 表示向内 ,0表示向外) : ");
    	   Scanner input2 = new Scanner(System.in);
    	   choice=input2.nextInt();
           if(choice==0)     //选择移动臂方向向外,则先向外扫描
    	   {
    		   System.out.println("磁盘扫描序列为:");
    		   System.out.print(now);
               for(j = left;j >= 0;j--)  //往磁道号小的方向扫描,即向外扫描
    		   {
    			  System.out.print( " --> "+ cidao[j]);
    		   }
               for(j=right;j<m;j++)   //磁头移动到最小号,则改变方向向内扫描未扫描的磁道
    		   {
    			  System.out.print(" --> " + cidao[j]);
    		   }
               sum=now-2*cidao[0]+cidao[m-1]; //还是拿55 66 72 88 93 100举例子,当前磁道号是90,那么90先会往内扫描,扫描到最小号
    	   }                                //然后在转回到了right=93处,又再一次经过了now,然后向右扫描到最大号
                                           //所以可以这么算sum =(now-cidao[0])*2 + (cidao[m-1]-now)
           
           
           else     //选择移动臂方向向外,则先向外扫描
    	   {
    		   System.out.println("磁盘扫描序列为:");
    		   System.out.print(now);
               for(j=right;j<m;j++)
    		   {
    			  System.out.print(" --> " + cidao[j]);
    		   }
               for(j=left;j>=0;j--)    //磁头移动到最大号,则改变方向向外扫描未扫描的磁道
    		   {
    			  System.out.print(" --> " + cidao[j]);
    		   }
               sum=-now-cidao[0]+2*cidao[m-1]; //同理sum =(cidao[m-1]-now)*2 + (now - cidao[0])
    	   }
       }
       ave=sum/(float)(m);
       System.out.println();
       System.out.print("平均寻道长度: " + ave);
    }
    
    

    2.5.4 CSCAN关键代码

    
     /**这个也要先排序,这里是升序,循环扫描也有三种情况
      * 1、若当前磁道号大于请求序列中最大者,则直接将移动臂移动到最小号磁道依次向内给予各请求服务 
      * 2、若当前磁道号小于请求序列中最小者,则直接由外向内依次给予各请求服务,就和SSTF一样了
      * 3、若当前磁道号大于请求序列中最小者且小于最大者
      * 循环扫描算法(即单向扫描,没有访问时磁头不动,若访问到最小号则直接跳到最大号往最小号单向扫描,反之一样。)
      * @param cidao //存的是磁道号
      * @param m
      */
    void CSCAN(int cidao[],int m)        //我默认是扫描方向是先向磁道号变小的方向进行,即从内到外
    {
       int k=1;
       int now = -1,left = -1,right = -1;
       int i,j,sum=0;
       float ave;
        Arrays.sort(cidao);
        System.out.println("排序后:");
        for (int n = 0; n < cidao.length; n++) {
     	System.out.print(cidao[n] + "  ");
     }
        System.out.println();
        System.out.print("请输入当前的磁道号:");
    	Scanner input = new Scanner(System.in);
    	now=input.nextInt();
       if(cidao[m-1]<=now)   //第一种情况:若当前磁道号大于请求序列中最大者,则直接将移动臂移动到最小号磁道依次向内给予各请求服务 
       {
    	  System.out.println("磁盘扫描序列为:");
    	  System.out.print(now);
          for(i=m-1;i>=0;i--)
          System.out.print( " --> " + cidao[i]);
          sum=now-cidao[0]; //和SCAN算法一样 55 66 72 88 93 100 当前磁道号为101
       }                    
       
       
       if(cidao[0]>=now) //第二种情况:若当前磁道号小于请求序列中最小者,则移动磁道到最大位置由外向内依次给予各请求服务,
       {
    	  System.out.println("磁盘扫描序列为:");
    	  System.out.print(now);
          for(i=m-1;i>=0;i--)
          System.out.print(" --> " + cidao[i]);
          sum=2*cidao[m-1]-now-cidao[0];   //55 66 72 88 93 100 当前磁道号54
       }                        //sum = (cidao[m-1] - now) + (cidao[m-1]-cidao[0])
       
       
       if(now>cidao[0]&&now<cidao[m-1])  //第三种情况:若当前磁道号大于请求序列中最小者且小于最大者
       {
    	  System.out.println("磁盘扫描序列为:");
    	  System.out.print(now);
          while(cidao[k]<now)    //同上,先找到当前磁道号的位置
    	  {
              k++;
    	  }
          left= k-1;
          right = k;
          for(j=left;j>=0;j--)          //因为是默认先扫描最小磁道号在移到最大磁道号扫描
    	  {                             //例:55 66 72 88 93 100 当前磁道号90
    		  System.out.print( " --> "+ cidao[j]);
    	  }
          for(j=m-1;j>left;j--) //当扫描完最小号磁道,磁头直接移动到最大号磁道,再向外扫描未扫描的磁道
    	  {
    		  System.out.print( " --> " + cidao[j]);
    	  }
          sum=2*cidao[m-1]-cidao[right]+now-2*cidao[0];//sum=(now-cidao[0])+(cidao[m-1]-cidao[0])+(cidao[m-1]-cidao[right])
       }
       ave=sum/(float)(m);
       System.out.println();
       System.out.println("平均寻道长度: " + ave );
    }
     
    }
    

    2.5.5 完整代码

    package DiskManage;
    import java.util.Scanner;
    import java.util.Arrays;
    /**
     * 磁盘调度FCFS、SSTF、SCAN、CSCAN
     * @author Monster丶ZF
     * @version1.8
     * @data 2019年7月2日
     * @remakeTODO
     */
    
        public class DiskManage{
    	public static void main(String[] args){
    		/*
    		要用到的几种算法分别是
    		冒泡排序算法
    		先来先服务调度算法
    		最短寻道时间优先调度算法
    		扫描调度算法
    		循环扫描调度算法
    		*/
    		DiskManage A = new DiskManage();
    		   
       int choice = -1; 
       int[] cidao={55,72,100,88,93,66}; //用来存磁道号
       //int[] cidao = new int[6];
       int i = -1;     //全局变量i
       int[] str=new int[6];
       
       System.out.println("随机产生一个磁道序列(包含6个磁道)\n");
       
    //   for(i=0;i<6;i++){
    //   		str[i]=(int)(Math.random()*100); //随机产生一个0-100的磁道号
    //   		cidao[i]=str[i];
    //   }
       
       System.out.println("随机得到的磁道序列为:");
       
       for(i=0;i<6;i++)    
       {
    	  System.out.print(cidao[i]+"  ");
       }
       System.out.println();
       while(true)
       {
          System.out.println();
    	  System.out.println("----------------------------------------------");
    	  System.out.println("|                 增福系统菜单                                 |");
    	  System.out.println("|                                            |");
    	  System.out.println("|               1. 先来先服务                                   |");
    	  System.out.println("|               2. 最短寻道时间优先                        |");
    	  System.out.println("|               3. 扫描(电梯)调度                        |");
    	  System.out.println("|               4. 循环扫描                                      |");
    	  System.out.println("|               5. 退出增福菜单                               |");
    	  System.out.println("----------------------------------------------");
    	  System.out.print("请选择算法:");
    	  Scanner input =new Scanner(System.in);
    	  choice=input.nextInt();     
          if(choice==5){
          System.err.println("已成功退出增福程序!");
            break;
          }
          switch(choice)
    	  {
             case 1:    //使用FCFS算法
             A.FCFS(cidao,6);
             break;
             case 2:    //使用SSTF算法
             A.SSTF(cidao,6);
             break;
             case 3:    //使用SCAN算法
             A.SCAN(cidao,6);
             break;
             case 4:    //使用CSCAN算法
             A.CSCAN(cidao,6);
             break;
             default: 
             System.err.println("请输入1-5之间的数字");
    	  }
       }
    	}
    	
    	/**
    	 * 先来先服务算法
    	 * @param cidao 要访问的磁道数组
    	 * @param m
    	 */
    	void FCFS(int cidao[],int m)   //磁道号数组,个数为m 
    {
        int now = -1;     //当前磁道号
        int sum = 0;	 //总寻道长度
        int i;
        float ave=0.0f;   //平均寻道长度
    	System.out.println("磁盘请求序列为:");
        for( i=0;i<m;i++)   //按先来先服务的策略输出磁盘请求序列
        {
    		System.out.print(cidao[i]+"  ");
        }
    	System.out.println();
    	System.out.print("请输入当前的磁道号:");
    	Scanner input = new Scanner(System.in);
    	  now=input.nextInt();
        sum+=Math.abs(cidao[0]-now);//求当前输入磁道和第一要访问磁道的距离
    	System.out.println("磁盘扫描序列为:");
    	System.out.print( now);
        for( i=0;i<m;i++)   //输出磁盘扫描序列
        {
    		System.out.print( " --> " + cidao[i]);
        }
        for(i=0;i<m-1;i++)   //求平均寻道长度 
        {
            sum+=Math.abs(cidao[i+1]-cidao[i]);
            ave=(float)sum/m;
        }
    	System.out.println();
    	System.out.println("平均寻道长度:"+ave);
    }
     
    	
    	
    	/**有三种情况:前提是先按升序排序好
    	 * 1、若当前磁道号大于请求序列中最大者,则直接由内向外依次给予各请求服务
    	 * 2、若当前磁道号小于请求序列中最小者,则直接由外向内依次给予各请求服务,与第一种同理
    	 * 3、若当前磁道号大于请求序列中最小者且小于最大者
    	 * 最短寻到时间优先算法
    	 * @param cidao 要访问的磁道数组
    	 * @param m
    	 */
    void SSTF(int cidao[],int m)
    {
       int k=1;                   //用于第三种情况找到当前磁道号在排序好序列的位置
       int now = -1,left = -1,right = -1;
       int i,j,sum=0;
     
       float ave = 0.0f;     //用来存平均寻道长度
       Arrays.sort(cidao); //调用快速排序算法升序处理
       System.out.println("排序后:"); 
       for (int n = 0; n < cidao.length; n++) {
    	System.out.print(cidao[n] + "  ");
    }
       System.out.println();
       System.out.print("请输入当前的磁道号:");
    	Scanner input =new Scanner(System.in);
    	now = input.nextInt(); 
    	                        //注:柱面的编号是从外到内从0开始编号的
       if(cidao[m-1]<=now)     // 第一种种情况:若当前磁道号大于请求序列中最大者,则直接由内向外依次给予各请求服务
       {                       //比如:排序后 55 66 72 88 93 100 若当前磁道大于100就直接从100开始予以各请求服务
    	  System.out.println("磁盘扫描序列为:");
    	  System.out.print(now);
          for(i=m-1;i>=0;i--)
          System.out.print(" --> " + cidao[i]);
          sum=now-cidao[0];  
       }
       
       if(cidao[0]>=now)      // 第二种情况:若当前磁道号小于请求序列中最小者,则直接由外向内依次给予各请求服务,与第一种同理
       {                   
    	  System.out.println("磁盘扫描序列为:");
    	  System.out.print(now);
          for(i=0;i<m;i++)
    	  System.out.print( " --> " + cidao[i]);
          sum=cidao[m-1]-now;
       }
       
       if(now>cidao[0]&&now<cidao[m-1])   //第三种情况:若当前磁道号大于请求序列中最小者且小于最大者
       {
    	   System.out.println("磁盘扫描序列为:");
    	   
           while(cidao[k]<now)        //确定当前磁道在已排的序列中的位置
    	   {
              k++;                   //k从1开始找
                                     //例如:55 66 72 88 93 100 若当前磁道号为90 直到找到93才会跳出循环,此时k=4
    	   }
           left=k-1;                   //表示此时位置的左边逻辑下标  
           right=k;                     //表示此时位置的右边逻辑下表
           
           
           System.out.print(now); 
           while((left>=0)&&(right<m))    //当前磁道在请求序列范围内
        	                      
    	   {    
              if((now-cidao[left])<=(cidao[right]-now))       //选择与当前磁道最近的请求给予服务,
    		  {                                     //例如90和88比较在和93比较看谁距离短就先给哪个服务
    			 System.out.print( " --> " + cidao[left]); //这是左边距离近的情况
                 sum+=now-cidao[left];
                 now=cidao[left];
                 left=left-1;
    		  }
              else
    		  {  //System.out.print(now);
    			 System.out.print( " --> " + cidao[right]);  //这是右边距离近的情况
                 sum+=cidao[right]-now;
                 now=cidao[right];
                 right=right+1;
    		  }
    	   }
           
           if(left==-1)   //磁头移动到序列的最小号,返回内侧扫描仍未扫描的磁道
    	   {
              for(j=right;j<m;j++)
    		  {
    			 System.out.print( "--> "+ cidao[j]);
    		  }
              sum+=cidao[m-1]-cidao[0];
    	   }
           else      //磁头移动到序列的最大号,返回外侧扫描仍未扫描的磁道
    	   {
              for(j=left;j>=0;j--)
    		  {
    			 System.out.print( "--> "+ cidao[j]);//例如55 66 72 88 93 100假设当前磁道90
    		  }                                      //则按前面的算法会有90-->88-->93-->100,此时到100时right+1=6跳出循环
              sum+=cidao[m-1]-cidao[0];              //来到了else这个分支,把磁头转到之前left的位置循环输出
    	   }                                         //那个sum直接等于最后一个减去第一个,因为他总是会扫描到最外侧的磁道号
       }                                             //和(100-72)+(72-66)+(66-55)= 100-55 = 45 是一样的
       
       ave=sum/(float)(m);
       System.out.println();
       System.out.println("平均寻道长度: "+ave);
    }
     
    /**
     * 这个算法和最短寻道差不多一样的,先排序,也有三种情况,但是多了一个选择移动臂的方向
     * 1、若当前磁道号大于请求序列中最大者,则直接由内向外依次给予各请求服务
     * 2、若当前磁道号小于请求序列中最小者,则直接由外向内依次给予各请求服务
     * 3、第三种情况:若当前磁道号大于请求序列中最小者且小于最大者
     * 扫描算法(电梯算法)
     * @param cidao  用来存磁道号
     * @param m
     */
    void SCAN(int cidao[],int m)    //先要给出当前磁道号和移动臂的移动方向
    {
       int k=1;
       int now,left = -1,right = -1 ,choice = -1 ;
       int i,j,sum=0;
       float ave = 0.0f;
       Arrays.sort(cidao);
    System.out.println("排序后:");
       
       for (int n = 0; n < cidao.length; n++) {
    	System.out.print(cidao[n] + "  ");
    }
       System.out.println();
        System.out.print("请输入当前的磁道号:");
    	Scanner input =new Scanner(System.in);
    	now = input.nextInt();
       if(cidao[m-1]<=now)    //第一种情况:若当前磁道号大于请求序列中最大者,则直接由内向外依次给予各请求服务
       {   
    	  System.out.println("磁盘扫描序列为:");
    	  System.out.print(now);
          for(i=m-1;i>=0;i--)
    	  System.out.print( " --> " + cidao[i]);
          sum=now-cidao[0];   //反正都要扫描到最外侧,直接减最小的那个得的距离和一个一个减在相加是等价的
       }
       if(cidao[0]>=now)     //第二种情况:若当前磁道号小于请求序列中最小者,则直接由外向内依次给予各请求服务
       {   
    	  System.out.println("磁盘扫描序列为:");
    	  System.out.print(now);
          for(i=0;i<m;i++)
          System.out.print(" --> " + cidao[i]);
          sum=cidao[m-1]-now;        //同理
       }
       if(now>cidao[0]&&now<cidao[m-1])   //第三种情况:若当前磁道号大于请求序列中最小者且小于最大者
       {
           while(cidao[k]<now) //和SSTF算法一样先找到当前寻道号的位置
    	   {
               k++;
    	   }
           left=k-1;
           right=k;
    	   System.out.println("请输入当前移动臂的移动的方向 (1 表示向内 ,0表示向外) : ");
    	   Scanner input2 = new Scanner(System.in);
    	   choice=input2.nextInt();
           if(choice==0)     //选择移动臂方向向外,则先向外扫描
    	   {
    		   System.out.println("磁盘扫描序列为:");
    		   System.out.print(now);
               for(j = left;j >= 0;j--)  //往磁道号小的方向扫描,即向外扫描
    		   {
    			  System.out.print( " --> "+ cidao[j]);
    		   }
               for(j=right;j<m;j++)   //磁头移动到最小号,则改变方向向内扫描未扫描的磁道
    		   {
    			  System.out.print(" --> " + cidao[j]);
    		   }
               sum=now-2*cidao[0]+cidao[m-1]; //还是拿55 66 72 88 93 100举例子,当前磁道号是90,那么90先会往内扫描,扫描到最小号
    	   }                                //然后在转回到了right=93处,又再一次经过了now,然后向右扫描到最大号
                                           //所以可以这么算sum =(now-cidao[0])*2 + (cidao[m-1]-now)
           
           
           else     //选择移动臂方向向外,则先向外扫描
    	   {
    		   System.out.println("磁盘扫描序列为:");
    		   System.out.print(now);
               for(j=right;j<m;j++)
    		   {
    			  System.out.print(" --> " + cidao[j]);
    		   }
               for(j=left;j>=0;j--)    //磁头移动到最大号,则改变方向向外扫描未扫描的磁道
    		   {
    			  System.out.print(" --> " + cidao[j]);
    		   }
               sum=-now-cidao[0]+2*cidao[m-1]; //同理sum =(cidao[m-1]-now)*2 + (now - cidao[0])
    	   }
       }
       ave=sum/(float)(m);
       System.out.println();
       System.out.print("平均寻道长度: " + ave);
    }
     
    
    
     /**这个也要先排序,这里是升序,循环扫描也有三种情况
      * 1、若当前磁道号大于请求序列中最大者,则直接将移动臂移动到最小号磁道依次向内给予各请求服务 
      * 2、若当前磁道号小于请求序列中最小者,则直接由外向内依次给予各请求服务,就和SSTF一样了
      * 3、若当前磁道号大于请求序列中最小者且小于最大者
      * 循环扫描算法(即单向扫描,没有访问时磁头不动,若访问到最小号则直接跳到最大号往最小号单向扫描,反之一样。)
      * @param cidao //存的是磁道号
      * @param m
      */
    void CSCAN(int cidao[],int m)        //我默认是扫描方向是先向磁道号变小的方向进行,即从内到外
    {
       int k=1;
       int now = -1,left = -1,right = -1;
       int i,j,sum=0;
       float ave;
        Arrays.sort(cidao);
        System.out.println("排序后:");
        for (int n = 0; n < cidao.length; n++) {
     	System.out.print(cidao[n] + "  ");
     }
        System.out.println();
        System.out.print("请输入当前的磁道号:");
    	Scanner input = new Scanner(System.in);
    	now=input.nextInt();
       if(cidao[m-1]<=now)   //第一种情况:若当前磁道号大于请求序列中最大者,则直接将移动臂移动到最小号磁道依次向内给予各请求服务 
       {
    	  System.out.println("磁盘扫描序列为:");
    	  System.out.print(now);
          for(i=m-1;i>=0;i--)
          System.out.print( " --> " + cidao[i]);
          sum=now-cidao[0]; //和SCAN算法一样 55 66 72 88 93 100 当前磁道号为101
       }                    
       
       
       if(cidao[0]>=now) //第二种情况:若当前磁道号小于请求序列中最小者,则移动磁道到最大位置由外向内依次给予各请求服务,
       {
    	  System.out.println("磁盘扫描序列为:");
    	  System.out.print(now);
          for(i=m-1;i>=0;i--)
          System.out.print(" --> " + cidao[i]);
          sum=2*cidao[m-1]-now-cidao[0];   //55 66 72 88 93 100 当前磁道号54
       }                        //sum = (cidao[m-1] - now) + (cidao[m-1]-cidao[0])
       
       
       if(now>cidao[0]&&now<cidao[m-1])  //第三种情况:若当前磁道号大于请求序列中最小者且小于最大者
       {
    	  System.out.println("磁盘扫描序列为:");
    	  System.out.print(now);
          while(cidao[k]<now)    //同上,先找到当前磁道号的位置
    	  {
              k++;
    	  }
          left= k-1;
          right = k;
          for(j=left;j>=0;j--)          //因为是默认先扫描最小磁道号在移到最大磁道号扫描
    	  {                             //例:55 66 72 88 93 100 当前磁道号90
    		  System.out.print( " --> "+ cidao[j]);
    	  }
          for(j=m-1;j>left;j--) //当扫描完最小号磁道,磁头直接移动到最大号磁道,再向外扫描未扫描的磁道
    	  {
    		  System.out.print( " --> " + cidao[j]);
    	  }
          sum=2*cidao[m-1]-cidao[right]+now-2*cidao[0];//sum=(now-cidao[0])+(cidao[m-1]-cidao[0])+(cidao[m-1]-cidao[right])
       }
       ave=sum/(float)(m);
       System.out.println();
       System.out.println("平均寻道长度: " + ave );
    }
     
    }
    

    4运行结果及分析
    4.1运行结果

    SSTF结果图2-1在这里插入图片描述
    SCAN结果图2-2
    在这里插入图片描述
    CSCAN结果图2-3在这里插入图片描述
    随机产生磁道号SSTF结果图2-4加粗样式在这里插入图片描述
    在这里插入图片描述
    3.运行分析
    (1)上面前三个结果是课本上的6个数据,因为FCFS比较简单,就不拿出来截图了,首先运行会弹出一个菜单,让你选择相应的调度算法,选择其中一个即可,也可以一直选择直到选择5退出,经过和课本比对和验算,磁道访问顺序和平均寻道时间都是正确的。

    (2)图2-4是随机数产生的磁道号,我选择了第2算法示例,他会先排好序,然后开始算法,经过验算也是正确的,包括其他算法自己也私下验证了,都是正确的具有通用性。同时我还添加了一些提示,如果用户不小心输入的数字不是1-5就会弹出提示,然后让用户重新输入1-5之间的数字,如果没有要计算的就选择5退出程序即可。

    展开全文
  • 磁盘调度算法的实现

    2019-01-05 22:28:05
    Java编程实现模拟FCFS、SSTF、SCAN的磁盘调度程序, ui界面。该程序设计系统首面输入磁道序列,主面可以选择某种算法并算出磁头移动的总磁道数以及平均磁道数。并且在面板上显示计算算信息
  • 处理器调度算法: 先来先服务, 时间片轮转, 短作业优先, 最高响应比优先 存储管理: FIFO, LRU 磁盘移臂调度: SSTF, SCAN 文件管理: 运用空闲盘块表的方式组织磁盘空间, 模拟文件的 create() 和 delete() 操作
  • 操作系统磁盘调度算法Let us compare various disk scheduling algorithms: 让我们比较一下各种磁盘调度算法 : 1. FCFS (1. FCFS) In FCFS, the requests are addressed in the sequence they come in the disk ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 28,015
精华内容 11,206
关键字:

java磁盘调度算法

java 订阅