【多级反馈队列】【操作系统cpu时间片切换模拟】java代码实现

思路

多级反馈队列多用于操作系统或其他存在线程分发工具类对cpu时间片的分发,一般情况下遵循时间耗时短的任务优先执行,耗时较久的任务在后执行且运行时间不超过单位时间片。

代码实现

任务构造类

该类用于模拟需要系统执行的任务,构造方法为该任务名称和工作任务,工作任务在这里用整型int表示,-1表示执行完成一次,若任务执行完毕则返回false表示该任务可以从任务队列中排除。

public class Task{

    private int taskWork;
    private String name;

    public Task(String name,int taskWork){
        this.name = name;
        this.taskWork = taskWork;
    }
    public int getTaskWork() {
        return taskWork;
    }

    public String getName() {
        return name;
    }

    public boolean runWork(){
        if(this.taskWork>0){
            this.taskWork--;
            return true;
        }
        return false;
    }
}

任务队列

此处选用阻塞队列作为任务队列,好处在于当队列满了之后入队数据并不会被抛弃,而且阻塞当前线程,直到队列有空间插入为止。
任务队列用于存储Task类,表示需要执行的任务。

public class TaskQueue {

    private ArrayBlockingQueue<Task> queue = new ArrayBlockingQueue<Task>(100);

    public void addTask(Task task) throws InterruptedException {
        this.queue.put(task);
    }

    public int getQueueSize(){
        return this.queue.size();
    }

    public Task getTask(){
        return this.queue.peek();
    }

    public void finishTask(){
        this.queue.poll();
    }

}

控制台类

用于处理任务的执行,分发,监控

控制台类构造

此处构造三个任务队列,用于归类存储不同优先级的任务
三个线程:creatWork线程用于创建Task类并分发至各个任务队列。watch线程用于监控各任务队列的任务情况。work线程用于处理各个队列的任务。

    private TaskQueue taskQueue1;
    private TaskQueue taskQueue2;
    private TaskQueue taskQueue3;
    private Thread creatWork;
    private Thread watch;
    private Thread work;

createWork线程

在这里不停随机生成0~300的随机数作为线程工作内容填入三个线程队列。0-100至第一个任务队列,100-200至第二个任务队列,200-300至第三个任务队列。每100ms创建一个任务并入队

                Random r = new Random();
                int i = 0;
                Task t;
                while(true){
                    try {
                        i = r.nextInt(300);
                        if(i<100){
                            t = new Task(i+"任务",i);
                            taskQueue1.addTask(t);
                        }else if(100<=i && i<200){
                            t = new Task(i+"任务",i);
                            taskQueue2.addTask(t);
                        }else{
                            t = new Task(i+"任务",i);
                            taskQueue3.addTask(t);
                        }
                        sleep(100);
                    } catch (InterruptedException e) {
                         e.printStackTrace();
                    }
                }
            }

watch线程

监控线程每秒对任务队列进行以此扫描.。

                while(true){
                    try {
                    System.out.println("------------任务队列1任务数:"+taskQueue1.getQueueSize());
                    System.out.println("------------任务队列2任务数:"+taskQueue2.getQueueSize());
                    System.out.println("------------任务队列3任务数:"+taskQueue3.getQueueSize());
                    System.out.println("---------------------------------------------------");
                    sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }

work线程

工作线程用于执行完成任务队列中的任务,优先选取第一队列进行执行,其次第二,最次第三。执行任务由任务队列的peek()方法选取队头但不出队,并执行runWork()方法模拟,每毫秒执行一次Task对象的runWork方法,当对象的taskWork被递减为0时,返回true,此时线程认为该任务已经执行完成并让该任务队列执行poll()方法,将执行执行完的Task对象排除出该队列。
同时定义time变量为50,视为一个单位时间片,每次执行就递减,时间片消耗完或任务执行完都会导致此次runWork()方法执行完成。


            private boolean runWork(Task t,String queueName) throws InterruptedException {
                int time = 50;

                while(t.runWork() && time>=0){
                    sleep(1);
                    time--;
                }
                if(t.getTaskWork()==0){
                    System.out.println(queueName+"---------------"+t.getName()+"任务执行完成");
                    return true;
                }
                if(time<0){
                    System.out.println(queueName+"---------------"+t.getName()+"时间片用尽,切换任务执行");
                }
                return false;

            }

            @Override
            public void run() {
                Task t = null;
                try {
                    while(true) {
                        sleep(1);
                        if (taskQueue1.getQueueSize()>0) {
                            t = taskQueue1.getTask();
                            if (runWork(t,"任务队列1")) {
                                taskQueue1.finishTask();
                            }
                        } else if (taskQueue1.getQueueSize()==0 && taskQueue2.getQueueSize()>0) {
                            t = taskQueue2.getTask();
                            if (runWork(t,"任务队列2")) {
                                taskQueue2.finishTask();
                            }
                        } else if (taskQueue1.getQueueSize()==0 && taskQueue2.getQueueSize()==0 && taskQueue3.getQueueSize()>0) {
                            t = taskQueue3.getTask();
                            if (runWork(t,"任务队列3")) {
                                taskQueue3.finishTask();
                            }
                        } else {
                            System.out.println("-----------------------任务队列为空");
                        }
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

测试结果

模拟运行

------------任务队列1任务数:0
------------任务队列2任务数:0
------------任务队列3任务数:0
---------------------------------------------------
任务队列2---------------127任务时间片用尽,切换任务执行
任务队列2---------------127任务时间片用尽,切换任务执行
任务队列2---------------127任务任务执行完成
任务队列2---------------198任务时间片用尽,切换任务执行
任务队列1---------------78任务时间片用尽,切换任务执行
任务队列1---------------78任务任务执行完成
任务队列1---------------84任务时间片用尽,切换任务执行
任务队列1---------------84任务任务执行完成
任务队列1---------------44任务任务执行完成
任务队列1---------------77任务时间片用尽,切换任务执行
任务队列1---------------77任务任务执行完成
任务队列1---------------90任务时间片用尽,切换任务执行
------------任务队列1任务数:1
------------任务队列2任务数:3
------------任务队列3任务数:1
---------------------------------------------------
任务队列1---------------90任务任务执行完成
任务队列2---------------198任务时间片用尽,切换任务执行
任务队列2---------------198任务时间片用尽,切换任务执行
任务队列2---------------198任务任务执行完成
任务队列2---------------138任务时间片用尽,切换任务执行
任务队列2---------------138任务时间片用尽,切换任务执行
任务队列1---------------59任务时间片用尽,切换任务执行
任务队列1---------------59任务任务执行完成
任务队列2---------------138任务任务执行完成
任务队列1---------------18任务任务执行完成
任务队列2---------------133任务时间片用尽,切换任务执行
任务队列2---------------133任务时间片用尽,切换任务执行
任务队列2---------------133任务任务执行完成
任务队列2---------------104任务时间片用尽,切换任务执行
任务队列2---------------104任务任务执行完成
任务队列2---------------104任务时间片用尽,切换任务执行
------------任务队列1任务数:1
------------任务队列2任务数:2
------------任务队列3任务数:5
---------------------------------------------------
任务队列1---------------57任务时间片用尽,切换任务执行
任务队列1---------------57任务任务执行完成
任务队列2---------------104任务任务执行完成
任务队列1---------------59任务时间片用尽,切换任务执行
任务队列1---------------59任务任务执行完成
任务队列2---------------171任务时间片用尽,切换任务执行
任务队列2---------------171任务时间片用尽,切换任务执行
任务队列2---------------171任务时间片用尽,切换任务执行
任务队列2---------------171任务任务执行完成
任务队列2---------------184任务时间片用尽,切换任务执行
任务队列2---------------184任务时间片用尽,切换任务执行
任务队列2---------------184任务时间片用尽,切换任务执行
任务队列2---------------184任务任务执行完成
任务队列2---------------127任务时间片用尽,切换任务执行
任务队列1---------------40任务任务执行完成
任务队列2---------------127任务时间片用尽,切换任务执行
任务队列2---------------127任务任务执行完成
------------任务队列1任务数:0
------------任务队列2任务数:3
------------任务队列3任务数:8
---------------------------------------------------

完整代码

任务类

package multiLevelFeedbackQueer;

public class Task{

    private int taskWork;
    private String name;

    public Task(String name,int taskWork){
        this.name = name;
        this.taskWork = taskWork;
    }
    public int getTaskWork() {
        return taskWork;
    }

    public String getName() {
        return name;
    }

    public boolean runWork(){
        if(this.taskWork>0){
            this.taskWork--;
            return true;
        }
        return false;
    }
}

任务队列类

package multiLevelFeedbackQueer;

import java.util.concurrent.ArrayBlockingQueue;

public class TaskQueue {

    private ArrayBlockingQueue<Task> queue = new ArrayBlockingQueue<Task>(100);

    public void addTask(Task task) throws InterruptedException {
        this.queue.put(task);
    }

    public int getQueueSize(){
        return this.queue.size();
    }

    public Task getTask(){
        return this.queue.peek();
    }

    public void finishTask(){
        this.queue.poll();
    }

}

控制台类

package multiLevelFeedbackQueer;

import java.util.Random;

public class Console {
    private TaskQueue taskQueue1;
    private TaskQueue taskQueue2;
    private TaskQueue taskQueue3;
    private Thread creatWork;
    private Thread watch;
    private Thread work;

    public void start(){
        preRun();
        creatWork.start();
        watch.start();
        work.start();
    }

    private void preRun(){
        taskQueue1 = new TaskQueue();
        taskQueue2 = new TaskQueue();
        taskQueue3 = new TaskQueue();
        creatWork = new Thread(){
            @Override
            public void run() {
                Random r = new Random();
                int i = 0;
                Task t;
                while(true){
                    try {
                        i = r.nextInt(300);
                        if(i<100){
                            t = new Task(i+"任务",i);
                            taskQueue1.addTask(t);
                        }else if(100<=i && i<200){
                            t = new Task(i+"任务",i);
                            taskQueue2.addTask(t);
                        }else{
                            t = new Task(i+"任务",i);
                            taskQueue3.addTask(t);
                        }
                        sleep(100);
                    } catch (InterruptedException e) {
                         e.printStackTrace();
                    }
                }
            }
        };
        watch = new Thread(){
            @Override
            public void run() {
                while(true){
                    try {
                    System.out.println("------------任务队列1任务数:"+taskQueue1.getQueueSize());
                    System.out.println("------------任务队列2任务数:"+taskQueue2.getQueueSize());
                    System.out.println("------------任务队列3任务数:"+taskQueue3.getQueueSize());
                    System.out.println("---------------------------------------------------");
                    sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        };
        work = new Thread(){

            private boolean runWork(Task t,String queueName) throws InterruptedException {
                int time = 50;

                while(t.runWork() && time>=0){
                    sleep(1);
                    time--;
                }
                if(t.getTaskWork()==0){
                    System.out.println(queueName+"---------------"+t.getName()+"任务执行完成");
                    return true;
                }
                if(time<0){
                    System.out.println(queueName+"---------------"+t.getName()+"时间片用尽,切换任务执行");
                }
                return false;

            }

            @Override
            public void run() {
                Task t = null;
                try {
                    while(true) {
                        sleep(1);
                        if (taskQueue1.getQueueSize()>0) {
                            t = taskQueue1.getTask();
                            if (runWork(t,"任务队列1")) {
                                taskQueue1.finishTask();
                            }
                        } else if (taskQueue1.getQueueSize()==0 && taskQueue2.getQueueSize()>0) {
                            t = taskQueue2.getTask();
                            if (runWork(t,"任务队列2")) {
                                taskQueue2.finishTask();
                            }
                        } else if (taskQueue1.getQueueSize()==0 && taskQueue2.getQueueSize()==0 && taskQueue3.getQueueSize()>0) {
                            t = taskQueue3.getTask();
                            if (runWork(t,"任务队列3")) {
                                taskQueue3.finishTask();
                            }
                        } else {
                            System.out.println("-----------------------任务队列为空");
                        }
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };
    }

}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值