Java 模拟磁盘调度管理

老师布置的实习题目如下:

设计目的:

加深对请求磁盘调度管理实现原理的理解,掌握磁盘调度算法。

设计内容:

通过编程实现不同磁盘调度算法。

设定开始磁道号寻道范围,依据起始扫描磁道号和最大磁道号数,随机产生要进行寻道的磁道号序列。选择磁盘调度算法,显示该算法的磁道访问顺序,计算出移动的磁道总数和平均寻道总数。

常用的磁盘调度算法简介如下,请在以下算法中任意选择两种实现,并对算法性能进行分析对比。

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

2. 扫描算法SCAN:该算法不仅考虑到欲访问的磁道与当前磁道间的距离,更优先考虑的是磁头当前的移动方向。例如,当磁头正在自里向外移动时,SCAN算法所考虑的下一个访问对象,应是其欲访问的磁道既在当前磁道之外,又是距离最近的。这样自里向外地访问,直至再无更外的磁道需要访问时,才将磁臂换向为自外向里移动。

3.循环扫描算法CSCAN:CSCAN算法规定磁头单向移动,例如,只是自里向外移动,当磁头移到最外的磁道并访问后,磁头立即返回到最里的欲访问的磁道,亦即将最小磁道号紧接着最大磁道号构成循环,进行循环扫描。

代码如下:

import java.util.Scanner;
import java.util.Arrays;


class Cipandiaodu{
	public static void main(String[] args){
		/*
		要用到的几种算法分别是
		冒泡排序算法
		先来先服务调度算法
		最短寻道时间优先调度算法
		扫描调度算法
		循环扫描调度算法
		*/
		Cipandiaodu A=new Cipandiaodu();
   int a;
   int now;   
   int c; 
   int[] cidao=new int[1000];
   int i=0,count; 
   int[] str=new int[100];
   System.out.println("随机产生一个磁道序列(包含10个磁道)\n");
   for(i=0;i<10;i++){
   		str[i]=(int)(Math.random()*200);
   		cidao[i]=str[i];
   }
   count=i-1;     
   System.out.println("得到的磁道序列为:");
   for(i=0;i<count;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.print("请选择算法:");
	  Scanner w=new Scanner(System.in);
	  c=w.nextInt();     
      if(c==5)
        break;
      switch(c)
	  {
         case 1:    //使用FCFS算法
         A.FCFS(cidao,count);
         break;
         case 2:    //使用SSTF算法
         A.SSTF(cidao,count);
         break;
         case 3:    //使用SCAN算法
         A.SCAN(cidao,count);
         break;
         case 4:    //使用CSCAN算法
         A.CSCAN(cidao,count);
         break;
	  }
   }
	}
	
	void FCFS(int cidao[],int m)   //磁道号数组,个数为m 
{
    int now;//当前磁道号
    int sum=0;	//总寻道长度
    int j,i;
	int a;
    float ave=0;   //平均寻道长度
	System.out.println("磁盘请求序列为:");
    for( i=0;i<m;i++)   //按先来先服务的策略输出磁盘请求序列
    {
		System.out.print(cidao[i]+" ");
    }
	System.out.println();
	System.out.print("请输入当前的磁道号:");
	Scanner w=new Scanner(System.in);
	  now=w.nextInt();
    sum+=Math.abs(cidao[0]-now);
	System.out.println("磁盘扫描序列为:");
    for( i=0;i<m;i++)   //输出磁盘扫描序列
    {
		System.out.print(cidao[i]+" ");
    }
    for(i=0,j=1;j<m;i++,j++)   //求平均寻道长度
    {
        sum+=Math.abs(cidao[j]-cidao[i]);
        ave=(float)sum/m;
    }
	System.out.println();
	System.out.println("平均寻道长度:"+ave);
}

void SSTF(int cidao[],int m)
{
   int k=1;
   int now,l,r;
   int i,j,sum=0;
   int a;

   float ave;
   Arrays.sort(cidao);
 	System.out.print("请输入当前的磁道号:");
	Scanner w=new Scanner(System.in);
	now=w.nextInt();
   if(cidao[m-1]<=now)   //若当前磁道号大于请求序列中最大者,则直接由外向内依次给予各请求服务
   {
	  System.out.println("磁盘扫描序列为:");
      for(i=m-1;i>=0;i--)
      System.out.print(cidao[i]+" ");
      sum=now-cidao[0];
   }
   if(cidao[0]>=now)   //若当前磁道号小于请求序列中最小者,则直接由内向外依次给予各请求服务
   {
	  System.out.println("磁盘扫描序列为:");
      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++;
	   }
       l=k-1;
       r=k;
       while((l>=0)&&(r<m))   //当前磁道在请求序列范围内
	   {
          if((now-cidao[l])<=(cidao[r]-now))   //选择与当前磁道最近的请求给予服务
		  {
			 System.out.print(cidao[l]+" ");
             sum+=now-cidao[l];
             now=cidao[l];
             l=l-1;
		  }
          else
		  {
			 System.out.print(cidao[r]+" ");
             sum+=cidao[r]-now;
             now=cidao[r];
             r=r+1;
		  }
	   }
       if(l==-1)   //磁头移动到序列的最小号,返回外侧扫描仍未扫描的磁道
	   {
          for(j=r;j<m;j++)
		  {
			 System.out.print(cidao[j]+" ");
		  }
          sum+=cidao[m-1]-cidao[0];
	   }
       else    //磁头移动到序列的最大号,返回内侧扫描仍未扫描的磁道
	   {
          for(j=l;j>=0;j--)
		  {
			 System.out.print(cidao[j]+" ");
		  }
          sum+=cidao[m-1]-cidao[0];
	   }
   }
   ave=(float)(sum)/(float)(m);
   System.out.println();
   System.out.println("平均寻道长度: "+ave);
}

void SCAN(int cidao[],int m)    //先要给出当前磁道号和移动臂的移动方向
{
   int k=1;
   int now,l,r,d;
   int i,j,sum=0;
   int a;
   float ave;
   Arrays.sort(cidao);
    System.out.print("请输入当前的磁道号:");
	Scanner w=new Scanner(System.in);
	now=w.nextInt();
   if(cidao[m-1]<=now)    //若当前磁道号大于请求序列中最大者,则直接由外向内依次给予各请求服务,此情况同最短寻道优先
   {   
	  System.out.println("磁盘扫描序列为:");
      for(i=m-1;i>=0;i--)
	  System.out.print(cidao[i]+" ");
      sum=now-cidao[0];
   }
   if(cidao[0]>=now)     //若当前磁道号小于请求序列中最小者,则直接由内向外依次给予各请求服务,此情况同最短寻道优先
   {   
	  System.out.println("磁盘扫描序列为:");
      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)
	   {
           k++;
	   }
       l=k-1;
       r=k;
	   System.out.println("请输入当前移动臂的移动的方向 (1 表示向外 ,0表示向内) : ");
	   Scanner x=new Scanner(System.in);
	   d=x.nextInt();
       if(d==0)     //选择移动臂方向向内,则先向内扫描
	   {
		   System.out.println("磁盘扫描序列为:");
           for(j=l;j>=0;j--)
		   {
			  System.out.print(cidao[j]+" ");
		   }
           for(j=r;j<m;j++)   //磁头移动到最小号,则改变方向向外扫描未扫描的磁道
		   {
			  System.out.print(cidao[j]+" ");
		   }
           sum=now-2*cidao[0]+cidao[m-1];
	   }
       else     //选择移动臂方向向外,则先向外扫描
	   {
		   System.out.println("磁盘扫描序列为:");
           for(j=r;j<m;j++)
		   {
			  System.out.print(cidao[j]+" ");
		   }
           for(j=l;j>=0;j--)    //磁头移动到最大号,则改变方向向内扫描未扫描的磁道
		   {
			  System.out.print(cidao[j]+" ");
		   }
           sum=-now-cidao[0]+2*cidao[m-1];
	   }
   }	 
   ave=(float)(sum)/(float)(m);
   System.out.println();
   System.out.print("平均寻道长度: ");
}


void CSCAN(int cidao[],int m)
{
   int k=1;
   int now,l,r;
   int i,j,sum=0;
   int a;
   float ave;
    Arrays.sort(cidao);
    System.out.print("请输入当前的磁道号:");
	Scanner w=new Scanner(System.in);
	now=w.nextInt();
   if(cidao[m-1]<=now)   //若当前磁道号大于请求序列中最大者,则直接将移动臂移动到最小号磁道依次向外给予各请求服务 
   {
	  System.out.println("磁盘扫描序列为:");
      for(i=0;i<m;i++)
      System.out.print(cidao[i]+" ");
      sum=now-2*cidao[0]+cidao[m-1];
   }
   if(cidao[0]>=now) //若当前磁道号小于请求序列中最小者,则直接由内向外依次给予各请求服务,此情况同最短寻道优先
   {
	  System.out.println("磁盘扫描序列为:");
      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++;
	  }
      l=k-1;
      r=k;
      for(j=r;j<m;j++)
	  {
		  System.out.print(cidao[j]+" ");
	  }
      for(j=0;j<r;j++)     //当扫描完最大号磁道,磁头直接移动到最小号磁道,再向外扫描未扫描的磁道
	  {
		  System.out.print(cidao[j]+" ");
	  }
      sum=2*cidao[m-1]+cidao[l]-now-2*cidao[0];
   }
   ave=(float)(sum)/(float)(m);
   System.out.println();
   System.out.println("平均寻道长度: ");
}

}

如有不对,欢迎指出。
  • 3
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值