Java~操作系統實驗 模擬電梯調度算法,實現對磁盤的調度。

實驗內容

  • 模擬電梯調度算法,實現對磁盤的調度。

實驗目的

  • 磁盤是一種高速、大量旋轉型、可直接存取的存儲設備。它作爲計算機系統的輔助存儲器,負擔着繁重的輸入輸出任務,在多道程序設計系統中,往往同時會有若干個要求訪問磁盤的輸入輸出請示等待處理。系統可採用一種策略,儘可能按最佳次序執行要求訪問磁盤的諸輸入輸出請求,這就叫磁盤調度,使用的算法稱磁盤調度算法。磁盤調度能降低爲若干個輸入輸出請求服務所須的總時間,從而提高系統效率。本實驗要求學生模擬設計一個磁盤調度程序,觀察磁盤調度程序的動態運行過程。

實驗原理

  • 模擬電梯調度算法,對磁盤調度。
    磁盤是要供多個進程共享的存儲設備,但一個磁盤每個時刻只能爲一個進程服務。
    當有進程在訪問某個磁盤時,其他想訪問該磁盤的進程必須等待,直到磁盤一次工作結束。
    當有多個進程提出輸入輸出請求處於等待狀態,可用電梯調度算法從若干個等待訪問者中選擇一個進程,讓它訪問磁盤。當存取臂僅需移到一個方向最遠的所請求的柱面後,如果沒有訪問請求了,存取臂就改變方向。

完整代碼+測試

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());
    }
}

  • 結果
    在這裏插入圖片描述
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章