操作系统之早期磁盘调度算法 先来先服务(FCFS) 最短寻道时间优先(SSTF) java实现

本文介绍了磁盘调度中的两种算法:先来先服务(FCFS)和最短寻道时间优先(SSTF),详细阐述了它们的优缺点,并通过Java实现了这两个算法。实验目的是优化寻道时间,提高数据访问效率。FCFS虽然公平简单,但平均寻道时间较长,而SSTF则能减少每次磁头移动距离,但可能导致某些请求的饥饿问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

磁盘调度

实验内容:编写一个程序处理磁盘调度中寻道时间的策略。

实验目的:磁盘调度中寻道时间直接影响到数据访问的快慢,处理好磁盘寻道时间是关键。

实验题目

  • 采用先来先服务策略处理
  • 采用最短寻道策略处理

实验原理

先来先服务(FCFS)

优点:公平、简单,每个进程的请求都能依次得到处理
缺点:未对寻道进行优化,平均寻道时间较长

在这里插入图片描述

流程图

在这里插入图片描述

最短寻道时间优先(SSTF)

优点:平均每次磁头移动距离较近;寻道性能比 FCFS 好,但不能保证寻道时间最短

缺点:不能保证平均寻道时间最短且有可能引起某些请求的饥饿

在这里插入图片描述

流程图

在这里插入图片描述

实现

数据结构和符号说明

DiskDispatch为一个工具类,定义了仅有其子类能使用的

四个变量 start为磁道开始点、track为将要访问的磁道号数组、distanceSum移动距离总磁道数、movdistan为将要计算的移动距离数组。

方法distance(int a, int b)使用三元表达式计算出两个磁盘的距离。

内部类Track是自定义数据类型,内含磁道号和磁针调度到本磁道移动距离。

FCFS类即先来先服务实现类

SSTF类即最短寻道时间优先实现类

DiskDispatch磁盘公有类
package com.process.diskpatch;

import java.util.ArrayList;

public class DiskDispatch {

    /**
     * start为磁道开始点
     * track为将要访问的磁道号数组
     * distanceSum移动距离总磁道数
     * movdistan为将要计算的移动距离
     */
    protected int start;
    protected ArrayList<Integer> track;
    protected int distanceSum = 0;
    protected int[] movdistan;


    /**
     * 计算距离函数通过三元运算符返回两数绝对值
     */
    protected int distance(int a, int b) {
        return a > b ? a - b : b - a;
    }


    /**
     * 定义内部类 磁道类 包含磁道号 要想访问须达到的距离
     */
    static class Track {
        int diskName;
        int distance;
    }
}
FCFS先来先服务实现类
package com.process.diskpatch;

import java.util.ArrayList;
import java.util.Arrays;

public class FCFS extends DiskDispatch {


    // 构造器
    public FCFS(int start, ArrayList<Integer> track) {
        this.start = start;
        this.track = track;
        movdistan = new int[track.size()];
    }

    /**
     * 调度执行函数,进行此次先来先服务磁盘调度
     */
    public void run() {
        // 初始化磁针位置
        int needle = start;
        for (int i = 0; i < track.size(); i++) {
            // 求出移动距离并保存
            movdistan[i] = distance(needle, track.get(i));
            distanceSum += movdistan[i];
            // 更新指针位置
            needle = track.get(i);
        }
    }

    @Override
    public String toString() {
        return "\n先来先服务FCFS" +
                "\n从" + start + "号磁道开始" +
                "\n被访问的下一个磁道号\t" + track +
                "\n移动距离(磁道数)\t" + Arrays.toString(movdistan) +
                "\n总道数:"+distanceSum+"\t平均寻道长度:" + String.format("%.2f", (double) distanceSum / track.size());
    }
}
SSTF最短寻道时间优先实现类
package com.process.diskpatch;

import java.util.ArrayList;
import java.util.Arrays;

public class SSTF extends DiskDispatch {
    /**
     * trackSequence为SSTF调度的磁道号数组
     * len 为传出的磁道号数目
     */
    private int[] trackSequence;
    private int len;


    // 构造器
    public SSTF(int start, ArrayList<Integer> track) {
        this.start = start;
        this.track = track;
        this.len = track.size();
        movdistan = new int[len];
        trackSequence = new int[len];
    }

    /**
     * 调度执行函数,进行此次最短寻道时间优先磁盘调度
     */
    public void run() {
        // 初始化磁针位置
        int needle = start;
        for (int i = 0; i < len; i++) {
            // 求出移动距离的磁道号以及移动距离
            Track tc = shortest(needle, track);
            // 将算出的将要访问的下一磁道号、移动距离加入对应数组
            trackSequence[i] = tc.diskName;
            movdistan[i] = tc.distance;
            distanceSum += movdistan[i];
            // 更新指针位置以及磁道号列表,去除已经访问的磁道号
            needle = tc.diskName;
            // 此处使用包装类包装,避免当成索引
            track.remove(Integer.valueOf(tc.diskName));
        }
    }

    /**
     * 在给定范围内找出里磁针最近的磁道号
     *
     * @param needle 磁针当前位置
     * @param array  访问磁道号数组,即查找范围
     * @return 查找到的要访问的磁道号
     */
    public Track shortest(int needle, ArrayList<Integer> array) {
        // 各变量初始化 先默认第一个是距离最近的磁道
        Track tc = new Track();
        tc.diskName = array.get(0);
        tc.distance = distance(needle, array.get(0));
        // 进过遍历,若发现有离得更近的就替换
        for (int item :
                array) {
            if (distance(needle, item) < tc.distance) {
                tc.diskName = item;
                tc.distance = distance(needle, item);
            }
        }
        return tc;
    }

    @Override
    public String toString() {
        return "\n最短寻道时间优先SSTF" +
                "\n从" + start + "号磁道开始" +
                "\n被访问的下一个磁道号\t" + Arrays.toString(trackSequence) +
                "\n移动距离(磁道数)\t" + Arrays.toString(movdistan) +
                "\n总道数:"+distanceSum+"\t平均寻道长度:" + String.format("%.2f", (double) distanceSum / len);
    }
}
测试类
package com.process.diskpatch;

import java.util.ArrayList;

public class Test {
    public static void main(String[] args) {
        // 磁盘号顺序
        int[] track = new int[]{98, 183, 37, 122, 14, 124, 65, 67};
        ArrayList<Integer> ta = new ArrayList<>();
        for (int t : track) {
            ta.add(t);
        }

        // 先来先服务
        FCFS ff = new FCFS(53, ta);
        ff.run();
        System.out.println(ff);

        //最短寻道时间优先
        SSTF st = new SSTF(53, ta);
        st.run();
        System.out.println(st);

    }
}

运行截图

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SK Primin

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值