[JAVA] Implementation of operating system job scheduling

First in first out

Schedule tasks directly based on waiting time. When the task is loaded, the first to be loaded is the first to be scheduled.

Shortest task first

Schedule tasks directly based on service time. When multiple tasks are in the loading queue, the task with the shortest service time is scheduled first.

Highest response ratio first

Schedule tasks based on waiting time and service time.

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

When multiple tasks are in the load queue, the query response is scheduled before the highest task.

Code

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



}

Guess you like

Origin blog.csdn.net/qq_43621091/article/details/110382642