[JAVA] 操作系统作业调度实现

先进先出

直接根据等待时间调度任务。当任务被加载后,最先加载进来的最先调度。

最短任务优先

直接根据服务时间调度任务。当多个任务在加载队列中,查询最短服务时间的任务先调度。

最高响应比优先

根据等待时间和服务时间调度任务。

响应比:(等待时间 + 服务时间) / 服务时间

当多个任务在加载队列中,查询响应比最高的任务先调度。

代码实现

package job;

import java.math.BigDecimal;
import java.math.MathContext;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;

/**
 * @author wenei
 * @date 2020-11-30 8:37
 */
public class Test {
    
    

    enum JobStatus {
    
    
        /**
         * 等待 wait
         */
        W,

        /**
         * 就绪 ready
         */
        R,

        /**
         * 完成 finish
         */
        F
    }

    static class Job {
    
    
        // 到达时间
        Integer arrivalTime;
        // 服务时间
        Integer serviceTime;
        // 开始时间
        Integer startTime;
        // 结束时间
        Integer endTime;
        // 周转时间
        Integer cycleTime;
        // 带权周转时间
        BigDecimal weightedTurnaroundTime;
        // 作业状态 默认为等待
        JobStatus status = JobStatus.W;
        // 等待时间 times - arrivalTime
        // 要求服务时间 serviceTime
    }

    /**
     * 任务链表
     */
    private static LinkedList<Job> jobs = new LinkedList<>();

    /**
     * 就绪任务
     */
    private static LinkedList<Job> readyJobs = new LinkedList<>();

    /**
     * 时间量
     */
    private static int times = 0;

    // 统计用数据 region start

    /**任务个数*/
    private static int count = 0;

    /**总周转周期*/
    private static BigDecimal cycleTimeSum = BigDecimal.ZERO;

    /**总带权周转时间*/
    private static BigDecimal weightedTurnaroundTimeSum = BigDecimal.ZERO;;

    // region end

    private static void addJob(int arrivalTime, int serviceTime) {
    
    
        Job job = new Job();
        job.arrivalTime = arrivalTime;
        job.serviceTime = serviceTime;
        jobs.addLast(job);

        count++;
    }

    /**
     * 运行作业
     */
    private static void running(Job job) {
    
    
        // 开始时间
        job.startTime = times;
        // 完成时间
        job.endTime = job.startTime + job.serviceTime;
        // 周转时间
        job.cycleTime = job.endTime - job.arrivalTime;
        // 带权周转时间
        job.weightedTurnaroundTime = BigDecimal.valueOf(job.cycleTime)
                .divide(BigDecimal.valueOf(job.serviceTime), MathContext.DECIMAL32);
        job.status = JobStatus.F;

        times += job.serviceTime;
        // 加载当前times之前的任务到readyJobs中
        load();
        dips(job);
    }

    /**
     * 打印信息
     */
    private static void dips(Job job) {
    
    
        System.out.println("当前时间:     " + times);
        System.out.println("到达时间:" + job.arrivalTime);
        System.out.println("服务时间:" + job.serviceTime);
        System.out.println("开始执行时间:" + job.startTime);
        System.out.println("完成时间:" + job.endTime);
        System.out.println("周转时间:" + job.cycleTime);
        System.out.println("带权周转时间:" + job.weightedTurnaroundTime);
        System.out.println();

        cycleTimeSum = cycleTimeSum.add(BigDecimal.valueOf(job.cycleTime));
        weightedTurnaroundTimeSum = weightedTurnaroundTimeSum.add(job.weightedTurnaroundTime);
    }

    /**
     * 加载times时间已经到达的任务到readyJobs
     */
    private static void load() {
    
    
        Iterator<Job> iterator = jobs.iterator();
        while (iterator.hasNext()) {
    
    
            Job job = iterator.next();
            if (job.arrivalTime <= times) {
    
    
                iterator.remove();
                job.status = JobStatus.R;
                readyJobs.addLast(job);
            }
        }
    }

    /**
     * 统计信息
     */
    private static void total() {
    
    
        System.out.println();
        System.out.println("平均周转时间:" + cycleTimeSum
                .divide(BigDecimal.valueOf(count), MathContext.DECIMAL32));
        System.out.println("平均带权周转时间:" + weightedTurnaroundTimeSum
                .divide(BigDecimal.valueOf(count), MathContext.DECIMAL32));
    }

    public static void main(String[] args) {
    
    
        firstComeFirstService();
//        shortestJobFirst();
//        highestResponseRatioNext();


        total();
    }

    /**
     * 先进先出
     */
    private static void firstComeFirstService() {
    
    
        addJob(0, 4);
        addJob(1, 3);
        addJob(2, 5);
        addJob(3, 2);
        addJob(4, 4);

        // 初始化就绪任务队列
        load();
        // 如果times=0时没有任务被加载,那么times++,直到有任务被加载位置
        while (readyJobs.isEmpty()) {
    
    
            ++times;
            load();
        }
        while (!readyJobs.isEmpty()) {
    
    
            Job job = readyJobs.poll();
            running(job);
        }
    }

    /**
     * 最短任务优先
     */
    private static void shortestJobFirst() {
    
    
        addJob(0, 4);
        addJob(1, 3);
        addJob(2, 5);
        addJob(3, 2);
        addJob(4, 4);

        // 初始化就绪任务队列
        load();
        // 如果times=0时没有任务被加载,那么times++,直到有任务被加载位置
        while (readyJobs.isEmpty()) {
    
    
            ++times;
            load();
        }

        while (!readyJobs.isEmpty()) {
    
    
            Job minJob = null;
            int minServiceTime = Integer.MAX_VALUE;
            for(Job job : readyJobs) {
    
    
                if (job.serviceTime < minServiceTime) {
    
    
                    minJob = job;
                    minServiceTime = job.serviceTime;
                }
            }
            readyJobs.remove(minJob);
            running(minJob);
        }
    }

    /**
     * 高响应比优先调度算法
     */
    private static void highestResponseRatioNext() {
    
    
        addJob(0, 3);
        addJob(2, 6);
        addJob(4, 4);
        addJob(6, 5);
        addJob(8, 2);

        // 初始化就绪任务队列
        load();
        // 如果times=0时没有任务被加载,那么times++,直到有任务被加载位置
        while (readyJobs.isEmpty()) {
    
    
            ++times;
            load();
        }

        while (!readyJobs.isEmpty()) {
    
    
            Job bestJob = null;
            BigDecimal bestJobRatio = BigDecimal.ZERO;
            for(Job job : readyJobs) {
    
    
                // 计算当前任务的响应比 (等待时间 / 服务时间) + 1
                BigDecimal ratio = BigDecimal.valueOf(times - job.arrivalTime)
                        .divide(BigDecimal.valueOf(job.serviceTime), MathContext.DECIMAL32)
                        .add(BigDecimal.ONE);
                if (ratio.compareTo(bestJobRatio) > 0) {
    
    
                    bestJobRatio = ratio;
                    bestJob = job;
                }
            }
            readyJobs.remove(bestJob);
            running(bestJob);
        }
    }



}

猜你喜欢

转载自blog.csdn.net/qq_43621091/article/details/110382642