Java-进程调度算法

news2025/1/11 14:48:46

文章目录

  • 为什么要设置进程调度算法?
  • 分类
    • 1. 先进先出(FIFO)算法
      • 优缺点
      • FIFO代码示例
    • 2. 短作业优先(SJF)算法
      • 优缺点
      • 示例代码
    • 3. 优先级算法(Priority scheduling)
      • 优缺点
      • 示例代码
    • 4. 时间片轮转算法
      • 优缺点
      • 示例
  • 各个算法的区别
  • 总结

热烈欢迎各位大佬的到来:大哥天,大哥地,大哥是我的天地。
祝大哥,吃不愁穿不愁,不住平房住高楼

在这里插入图片描述

Java进程调度算法是计算机操作系统中非常重要的一个方面,它决定了在多个进程同时运行时,哪些进程将获得CPU时间片,以及执行时间如何分配。

为什么要设置进程调度算法?

Java中设置进程调度算法是为了有效地管理和分配CPU资源,以提高系统的性能和响应能力。

进程调度算法的选择可以根据不同的需求来进行,例如最短剩余时间优先算法(Shortest Remaining Time First, SRTF)可以保证短作业优先得到更快的响应时间,而轮转调度算法(Round Robin)可以平均分配CPU时间片,保证每个线程或进程都有机会执行。

通过设置合适的进程调度算法,可以避免线程或进程之间的饥饿情况,提高系统的吞吐量和效率。同时,进程调度算法也需要考虑到公平性、响应时间、吞吐量等方面的需求,以满足不同场景下的要求。

分类

Java进程调度算法可以基于不同的策略进行实现,包括但不限于以下几种:

1. 先进先出(FIFO)算法

这是最简单的进程调度算法,它按照进程到达时间的先后顺序依次分配CPU时间片。但是,它忽略了进程的优先级和执行时间,可能会导致长时间等待的进程被阻塞,进程执行效率低下。

优缺点

优点:

  • 实现简单,易于理解和实现。
  • 不会产生死锁,因为每个进程都按照它们进入系统的顺序依次执行。
  • 在处理一些短时间的进程时,可以保证较好的响应时间。

缺点:

  • 无法处理优先级,每个进程都被视为同等重要,可能导致低优先级进程被长时间忽略。
  • 无法考虑进程的执行时间,可能会导致某些进程长时间占用CPU,而其他进程则得不到足够的调度时间。
  • 在处理长时间运行的进程时,平均等待时间较长。

综上所述,FIFO算法在某些特定场景下是一种很好的选择,但在处理复杂的进程调度问题时,可能需要更为高级的算法来保证所有进程都能够公平地获得调度时间。

FIFO代码示例

以下是使用Java编写的一个简单的先进先出(FIFO)算法的进程调度代码示例:

import java.util.LinkedList;
import java.util.Queue;

public class ProcessSchedulerFIFO {
    private Queue<Process> queue;

    public ProcessSchedulerFIFO() {
        queue = new LinkedList<Process>();
    }

    public void addProcess(Process process) {
        queue.offer(process);
    }

    public void run() {
        while (!queue.isEmpty()) {
            Process process = queue.poll();
            process.execute(); // 执行进程
        }
    }

    public static void main(String[] args) {
        ProcessSchedulerFIFO scheduler = new ProcessSchedulerFIFO();

        // 构造多个进程示例
        Process p1 = new Process("Process 1", 10);
        Process p2 = new Process("Process 2", 5);
        Process p3 = new Process("Process 3", 8);

        scheduler.addProcess(p1);
        scheduler.addProcess(p2);
        scheduler.addProcess(p3);

        scheduler.run();
    }
}

// 定义Process类
class Process {
    private String name;
    private int executionTime;

    public Process(String name, int executionTime) {
        this.name = name;
        this.executionTime = executionTime;
    }

    public void execute() {
        System.out.println("Executing process " + name + " for " + executionTime + " seconds.");
        try {
            Thread.sleep(executionTime * 1000); // 模拟进程执行
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

在上面的示例中,我们创建了一个ProcessSchedulerFIFO类来实现先进先出算法。addProcess()方法将待执行的进程加入到队列中,run()方法按照队列的先进先出顺序依次执行每个进程。

我们还创建了一个Process类代表实际的进程。在execute()方法中,我们模拟了进程的执行,使用Thread.sleep()函数使线程休眠指定的时间。

在main()方法中,我们创建了3个Process实例并将它们添加到ProcessSchedulerFIFO队列中。最后,运行ProcessSchedulerFIFO的run()方法以按照先进先出顺序执行所有进程。

2. 短作业优先(SJF)算法

短作业优先(SJF)算法是一种基于执行时间的进程调度算法,这种调度算法考虑了每个进程的执行时间,对执行时间最短的进程优先进行调度。它可以最小化平均等待时间和平均周转时间,但可能导致长时间等待的进程被阻塞,而且需要提前准确评估进程的执行时间。

优缺点

它的主要优点是最小化平均等待时间和平均周转时间,因为它将最短的作业分配给CPU执行。以下是Java进程使用SJF算法的优缺点:

优点:

  • 最小化平均等待时间和平均周转时间,因为短作业被优先执行。
  • 对于长时间的作业,SJF算法可以保证不会一直等待,因为短作业会在它们之前被执行。

缺点:

  • SJF算法无法预测未来进程的执行时间,因此可能会出现长时间的等待时间。如果有一个长时间的作业在队列前面,那么后面的短作业就要等待很长时间才能得到执行。
  • SJF算法需要知道每个进程的执行时间,但在实际应用中很难预测。如果没有准确的执行时间信息,SJF算法就无法正常工作。
  • 如果有很多短作业,SJF算法会很好地处理它们,但对于长时间的作业,会有较长的等待时间。这意味着,SJF算法并不一定是适用于所有情况的最佳算法。

示例代码

以下是使用短作业优先算法的Java代码示例:

import java.util.*;

public class SJFProcessScheduler {

    public static void main(String[] args) {

        Scanner input = new Scanner(System.in);

        System.out.print("Enter the number of processes: ");
        int n = input.nextInt();

        int[] arrivalTime = new int[n];
        int[] burstTime = new int[n];
        int[] waitingTime = new int[n];
        int[] turnaroundTime = new int[n];
        boolean[] visited = new boolean[n];

        for (int i = 0; i < n; i++) {
            System.out.print("Enter the arrival time of process " + (i + 1) + ": ");
            arrivalTime[i] = input.nextInt();
            System.out.print("Enter the burst time of process " + (i + 1) + ": ");
            burstTime[i] = input.nextInt();
        }

        int totalWaitingTime = 0;
        int totalTurnaroundTime = 0;
        int totalProcessed = 0;
        int currentTime = 0;

        while (totalProcessed < n) {
            int shortestJobIndex = -1;
            int shortestJobTime = Integer.MAX_VALUE;
            for (int i = 0; i < n; i++) {
                if (!visited[i] && burstTime[i] < shortestJobTime && arrivalTime[i] <= currentTime) {
                    shortestJobTime = burstTime[i];
                    shortestJobIndex = i;
                }
            }
            if (shortestJobIndex == -1) {
                currentTime++;
            } else {
                waitingTime[shortestJobIndex] = currentTime - arrivalTime[shortestJobIndex];
                turnaroundTime[shortestJobIndex] = waitingTime[shortestJobIndex] + burstTime[shortestJobIndex];
                totalWaitingTime += waitingTime[shortestJobIndex];
                totalTurnaroundTime += turnaroundTime[shortestJobIndex];
                visited[shortestJobIndex] = true;
                totalProcessed++;
                currentTime += burstTime[shortestJobIndex];
            }
        }

        double averageWaitingTime = (double) totalWaitingTime / n;
        double averageTurnaroundTime = (double) totalTurnaroundTime / n;

        System.out.println("Average waiting time: " + averageWaitingTime);
        System.out.println("Average turnaround time: " + averageTurnaroundTime);
    }
}

在这个示例中,输入包括每个进程的到达时间和执行时间。然后,计算出每个进程的等待时间和周转时间,并计算出平均等待时间和平均周转时间。该示例使用布尔数组来跟踪进程是否已被访问,以避免在同一时间执行多个进程。

3. 优先级算法(Priority scheduling)

该算法根据每个进程的优先级,对具有更高优先级的进程进行调度,以保证其获得更多的CPU时间片。但是,由于可能存在优先级反转问题,因此需要额外的机制来解决这个问题。

优缺点

优先级调度算法是一种根据优先级为进程分配处理器的算法。以下是Java进程使用优先级算法的优缺点:

优点:

  • 优先级调度算法可以根据进程的重要性分配处理器。优先级越高的进程会优先获得CPU时间,从而提高系统的响应速度和效率。
  • 这种算法可以满足实时系统的需求,例如控制系统、飞行模拟器和医疗设备等其它高优先级进程的需求。

缺点:

  • 如果进程的优先级不平衡,或者有一个进程的优先级极高,那么其他进程可能会得不到处理器时间。这可能会导致饥饿问题(Starvation),即某个进程永远无法获得CPU时间。
  • 如果发生优先级反转(Priority inversion),那么一些低优先级的进程可能会抢占高优先级进程的资源,比如锁。这可能会导致低优先级进程的执行时间非常长,从而降低了系统的响应速度和效率。
  • 在某些情况下,优先级调度算法可能无法满足进程的响应时间需求。这是因为某些高优先级进程可能在长时间内持有处理器时间,而低优先级进程需要等待很长时间才能获得CPU时间。

示例代码

以下是一个使用优先级算法的Java代码示例:

import java.util.Comparator;
import java.util.PriorityQueue;

public class PriorityScheduler {
    public static void main(String[] args) {
        // 定义一个进程类
        class Process {
            int pid; // 进程ID
            int priority; // 进程优先级

            public Process(int pid, int priority) {
                this.pid = pid;
                this.priority = priority;
            }
        }

        // 定义一个按照优先级排序的队列
        PriorityQueue<Process> queue = new PriorityQueue<>(new Comparator<Process>() {
            @Override
            public int compare(Process p1, Process p2) {
                return p2.priority - p1.priority;
            }
        });

        // 添加一些进程到队列中
        queue.offer(new Process(1, 5));
        queue.offer(new Process(2, 1));
        queue.offer(new Process(3, 3));
        queue.offer(new Process(4, 2));
        queue.offer(new Process(5, 4));

        // 取出队列中的进程并执行
        while (!queue.isEmpty()) {
            Process p = queue.poll();
            System.out.println("Process " + p.pid + " is running with priority " + p.priority);
            // 等待一段时间
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

在这个例子中,我们使用优先级优先的原则从优先级最高的进程开始执行,直到队列为空。在真实的操作系统中,优先级调度算法有更复杂的实现,通常还会考虑到各种因素,如时间片轮转、多级反馈队列等。

4. 时间片轮转算法

这是最常用的调度算法之一,它将所有进程分配相同长度的时间片,然后按顺序调度进程。每个进程在时间片结束时暂停,等待下一个时间片。这种算法可以确保公平性,并且不需要估计进程的执行时间。

优缺点

时间片轮转算法其优缺点如下:

优点:

  • 公平性:每个进程都有一个相同的时间片,可以公平地分配CPU资源。

  • 响应时间短:对于需要快速响应的进程,时间片轮转算法可以很快地将其放到CPU上运行。

  • 避免饥饿:由于每个进程只执行一段时间,因此无论优先级如何,每个进程都有机会被调度执行。

缺点:

  • 时间片大小的选择:如果时间片太小,会导致频繁的上下文切换,影响系统的性能;如果时间片太大,会导致进程响应时间变长。

  • 大量繁忙的进程:当系统中存在大量繁忙的进程时,时间片轮转算法可能无法有效利用CPU资源,因为每个进程只能运行一个时间片,而在时间片过期之前,其他进程无法获得CPU时间。

  • 不适合长时间运行的进程:对于需要长时间运行的进程,时间片轮转算法可能无法提供足够的CPU时间,因为进程只能在时间片内执行一定量的工作。

综上所述,时间片轮转算法是一种简单而公平的进程调度算法,适用于大多数通用的操作系统。但是,对于某些特定的应用场景,可能需要其他的进程调度算法来更好地支持应用程序的性能和稳定性。

示例

下面是Java进程使用时间片轮转算法的简单示例代码:

import java.util.LinkedList;
import java.util.Queue;

public class TimeSliceScheduler {
    // 定义时间片大小
    private static final int TIME_SLICE = 2;

    // 定义进程队列
    private Queue<Process> queue;

    // 构造函数初始化进程队列
    public TimeSliceScheduler() {
        queue = new LinkedList<>();
        queue.offer(new Process("P1", 6));
        queue.offer(new Process("P2", 5));
        queue.offer(new Process("P3", 4));
        queue.offer(new Process("P4", 3));
    }

    // 时间片轮转算法
    public void schedule() {
        while (!queue.isEmpty()) {
            // 取出队首进程
            Process process = queue.poll();

            // 运行进程
            process.run(TIME_SLICE);

            // 如果进程还未完成,则加入队列末尾
            if (!process.isFinished()) {
                queue.offer(process);
            }
        }
    }

    // 测试
    public static void main(String[] args) {
        TimeSliceScheduler scheduler = new TimeSliceScheduler();
        scheduler.schedule();
    }
}

// 进程类
class Process {
    private String name;  // 进程名
    private int total;    // 进程需要的时间
    private int executed; // 进程已经执行的时间

    public Process(String name, int total) {
        this.name = name;
        this.total = total;
        this.executed = 0;
    }

    // 运行进程
    public void run(int timeSlice) {
        int remaining = total - executed;
        int time = Math.min(timeSlice, remaining);
        executed += time;
        System.out.println("Process " + name + " executed " + time + " units (total " + executed + " units).");
    }

    // 判断进程是否执行完成
    public boolean isFinished() {
        return executed >= total;
    }
}

上面的代码使用Java语言实现了基本的时间片轮转算法。其中,使用一个进程队列来存储所有需要执行的进程,每次从队首取出一个进程并运行一个时间片,如果进程未完成,则重新加入队列末尾,直到队列为空为止。由于示例中每个进程的执行时间较短,因此示例只运行了一轮,实际应用中可能需要多轮执行才能完成所有进程的运行。

各个算法的区别

对四种算法从不同的维度进行了对比:
在这里插入图片描述

在Java中,我们可以通过java.util.concurrent包中的Executor框架执行进程调度。线程池和任务队列是实现Java进程调度算法的关键组件。线程池管理线程的数量和可用性,并且最小化线程创建的开销。任务队列则允许我们安排任务的执行顺序,例如FIFO或优先级排序。

总结

总而言之,Java进程调度算法是计算机操作系统中非常重要的方面,可以通过不同的调度算法实现。每种算法都有其优缺点,需要根据具体情况进行选择和使用。在Java中,我们可以使用线程池和任务队列来实现进程调度。

再次热烈欢迎各位大佬的到来:大哥天,大哥地,大哥是我的天地。
祝大哥,吃不愁穿不愁,不住平房住高楼

在这里插入图片描述
如果文章合您的胃口,麻烦您动动小手指给小弟来个一键三连,小弟万分感谢。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/915887.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

java 高级面试题整理(薄弱技术)

session 和cookie的区别和联系 session1.什么是session Session是另一种记录客户状态的机制&#xff0c;不同的是Cookie保存在客户端浏览器中&#xff0c;而Session保存在服务器上。客户端浏览器访问服务器的时候&#xff0c;服务器把客户端信息以某种形式记录在服务器上。这就…

Wireshark数据抓包分析之HTTP协议

一、实验目的&#xff1a; 主要时熟悉wireshark的使用 二、预备知识&#xff1a; HTTP协议的相关知识 what fk&#xff0c;原来只要在右页点击切换&#xff0c;就可以开启2台不同的机器欸&#xff01;nice 三、实验过程&#xff1a; 1.在机器1中通过管理员身份运行hfs之后&a…

5G网络优化基础班9月11号开班已定,零基础系统教学,带你入门+进阶+实战+就业!

1G、2G、3G时代&#xff0c;更多的是让人们了解和开始使用移动通讯&#xff0c;而随着技术的不断地迭代更新&#xff0c;4G改变生活&#xff0c;5G或将改变社会。5G是第五代移动通信技术的简称&#xff0c;它是一种全新的无线通信技术&#xff0c;将为人们带来更快、更稳定、更…

1.文章复现《热电联产系统在区域综合能源系统中的定容选址研究》(附matlab程序)

0.代码链接 文章复现《热电联产系统在区域综合能源系统中的定容选址研究》&#xff08;matlab程序&#xff09;-Matlab文档类资源-CSDN文库 1.简述 本文采用遗传算法的方式进行了下述文章的复现并采用电-热节点的方式进行了潮流计算以降低电网的网络损耗 分析了电网的基本数…

Java学习笔记38

Java笔记38 注解 什么是注解 Annotation是从 JDK 5.0 开始引入的新技术。Annotation的作用︰ 不是程序本身&#xff0c;可以对程序作出解释。&#xff08;这一点和注释 - comment没什么区别&#xff09;可以被其他程序&#xff08;比如编译器等&#xff09;读取。 Annotatio…

系统认知篇:防腐层、门面模式及适配模式的本质

门面模式和适配器模式是代码级的设计模式&#xff0c;而防腐层本质是一种 防御型策略 &#xff0c;在更高的层级对系统进行解耦 1 关于防腐层 Anti-Corruption Layer(ACL) 如下&#xff1a; Implement a faade or adapter layer between different subsystems that dont share…

用断言更好地实现替换重复出现的单词

断言是指对匹配到的文本位置有要求。也就是说&#xff0c;在有些情况下&#xff0c;我们对要匹配的文本的位置也有一定的要求。为了解决这个问题&#xff0c;正则中提供了一些结构&#xff0c;只用于匹配位置&#xff0c;而不是文本内容本身&#xff0c;这种结构就是断言。常见…

C++_Linux报错问题记录

1、致命错误&#xff1a;vector&#xff1a;没有那个文件或目录 解决&#xff1a;.c文件只会引用C语言的标准库&#xff0c;vecter是属于C的语法&#xff0c;把文件名称改成cpp即可 2、.cpp文件中下面编译语句报错&#xff1a;对‘std::cout’未定义的引用 gcc -o test test.…

docker 报错

问题说明&#xff1a;我是服务器上面的docker拉到本地30卡想用的&#xff0c;但是失败&#xff0c;报错如下&#xff1a; 服务器上面显存驱动是450&#xff0c;本地30卡驱动是470 nvidia-docker run -it --name 20230821_3 --shm-size 16g -p 10029:22 --privileged 20230821_i…

关于cloudflare的“检查站点连接是否安全”一直反复转圈的问题

前一段时间访问不少网站都会出现类似以下的信息&#xff1a; 其中很多时候哦是没有红色框框一栏&#xff0c;就是拼命在转圈和刷新页面&#xff0c;等上一个小时都没用。以上情况看很多网上的说法是卸载浏览器安装的插件。我寻思我也没安装过什么插件。 对于试过网上不少方法但…

java八股文面试[java基础]—— hashCode 与 equals 区别 == 与 equals的区别

两个对象的hashCode()相同时&#xff0c;equals()相等吗&#xff1f;_两个对象的hashcode一样,equal一样么_不想当个程序员的博客-CSDN博客 equals()&#xff1a;比较的是非基本类型的数据的引用地址&#xff08;即内存地址&#xff09;是否相同&#xff0c;但是对于重写equal…

Vulnhub: DOUBLE: 1靶机

kali&#xff1a;192.168.111.111 靶机&#xff1a;192.168.111.209 信息收集 端口扫描 nmap -A -sC -v -sV -T5 -p- --scripthttp-enum 192.168.111.209 目标80端口 sendcommand.php页面源码 写入webshell <?php system($_GET["cmd"]);?> 执行命令 ht…

不修改原图片,自动添加水印

只要添加我写的一个DynaWatermark2.1.1.jar的包,然后在web.xml里配置一下,哪个文件夹下的图片需要动态水印,就可以啦!以后通过页面访问这个文件夹下的图片,就会自动加上水印.但不会修改文件夹里图片本身.   这个jar里面有添加图片水印和文字水印两个servlet.(不能两个都配置,…

《golang设计模式》第二部分·结构型模式-03-组合模式(Composite)

文章目录 1. 概述1.1 角色1.2 类图 2. 代码示例2.1 设计2.2 代码2.3 类图 1. 概述 将叶子节点和复合节点组合起来&#xff0c;定义一个抽象接口遍历他们 1.1 角色 Component&#xff08;抽象构件&#xff09;&#xff1a;为叶子构件和复合构件声明接口&#xff0c;定义了结构…

Docker安装并运行Alertmanager

Linux下安装Docker请参考&#xff1a;Linux安装Docker 简介 Alertmanager是一个独立的告警模块&#xff0c;接收Prometheus等客户端发来的警报&#xff0c;之后通过分组、删除重复等处理&#xff0c;并将它们通过路由发送给正确的接收器&#xff1b;告警方式可以按照不同的规…

openCV实战-系列教程2:阈值与平滑处理(图像阈值/图像平滑处理/高斯/中值滤波)、源码解读

1、图像阈值 t图像阈值函数&#xff0c;就是需要判断一下像素值大于一个数应该怎么处理&#xff0c;小于一个数应该怎么处理 ret, dst cv2.threshold(src, thresh, maxval, type) 参数解析&#xff1a; src&#xff1a; 原始输入图&#xff0c;只能输入单通道图像&#…

/root/.ssh/config line 2: Bad protocol 2 host key algorithms ‘+ssh-rsa‘.

文章目录 1、问题2、查看openssh版本3、解决问题4、重新生成密钥5、查看是否可连接工蜂 1、问题 ssh访问工蜂报错&#xff1a; [rootlocalhost .ssh]# ssh -T gitgit.code.tencent.com /root/.ssh/config line 2: Bad protocol 2 host key algorithms ‘ssh-rsa’. 2、查看o…

如何识别芯片引脚1

当从上面看芯片时&#xff0c;引脚总是按逆时针方向编号。这来自于旧时代的电子管&#xff0c;当从电子管的底部看时&#xff0c;引脚是按顺时针方向编号的。 芯片的标记方式有多种&#xff0c;但是总有一些惯例可循。换句话说&#xff0c;如果你在一个未知的芯片上发现了这些标…

Linux的基础编程——Linux常用操作总结(十一)

前言&#xff1a; 前面我们已经对在Linux系统上的一些常用操作已经有了一个简单的入门与了解&#xff0c;后面的学习中我们还需要对这些操作常加练习&#xff0c;现在让我们对之前的一些常用操作进行的一个简单的总结吧 目录 一、软件安装 CentOS系统使用&#xff1a; Ubun…

pdf转换成excel怎么转换?看看这几种方法

pdf转换成excel怎么转换&#xff1f;转换PDF文件到Excel是一个常见的需求&#xff0c;因为许多工作需要将PDF文件转换成可编辑和可搜索的Excel电子表格。无论是在学校、办公室还是在家里&#xff0c;将PDF文件转换成Excel文件的需求都屡见不鲜。有时候&#xff0c;你可能需要将…