java可视化模拟进程调度算法—先来先服务算法
java可视化模拟进程调度算法—先来先服务算法
模拟内容
利⽤Java语⾔,模拟进程的调度过程,本篇博客中将通过先来先服务算法可视化模拟进程的调度过程,并且在模拟的过程中展⽰出就绪队列、阻塞队列、执⾏状态。
实验原理(理论)
先来先服务算法是最简单的调度算法,既可以⽤于作业调度 ,也可以⽤于程序调度,当作业调度中采⽤该算法时,系统将按照作业到达的先后次序来进⾏调度,优先从后备队列中,选择⼀个或多个位于队列头部的作业,把他们调⼊内存,分配所需资源、创建进程,然后放
⼊“就绪队列”,直到该进程运⾏到完成或发⽣某事件堵塞后,进程调度程序才将处理机分配给其他进程。
先来先服务算法的服务要领是:按照进程进⼊就绪队列的先后顺序调度并分配处理机执⾏。先来先服务调度算法是⼀种⾮抢占式的算法,先进⼊就绪队列的进程,先分配处理机运⾏。⼀旦⼀个进程占有了处
理机,它就⼀直运⾏下去,直到该进程完成⼯作或者因为等待某事件发⽣⽽不能继续运⾏时才释放处理机。
实验步骤及代码分析
1.任务定义
使⽤java编写可视化程序,通过在界⾯中绘制四个⼩球来模拟进程的调度,同时绘制其他形状的图形来代表就绪队列和CPU。点击“开始按钮”让⼩球以不同的速度(随机产⽣)开始运动,最先到达“CPU”边缘的⼩球优先通过“CPU”,其余的⼩球在“就绪队列”中等待,直到CPU空闲下⼀个⼩球继续向“CPU”运动。通过点击按钮“重置并开始”来恢复界⾯的初始状态并开始新的模拟过程。
2.界⾯设计
初始界⾯如下图所⽰,界⾯中有四个⼩球、两个长⽅形区域、⼀个正⽅形区域以及三个按钮。四个⼩球⽤来模拟四个进程的执⾏和调度过程,第⼀个长⽅形区域代表就绪队列,第⼆个长⽅形区域⽤来表⽰进程由就绪状态到执⾏状态的转变,正⽅形区域代表CPU,三个按钮分别是“开始”、“重置并开始”、“退出”。
3.算法设计
定义⼀个队列BallQueue⽤于存放⼩球,⼩球在开始运动时会随机获得不同的速度,这时会根据⼩球速度的⼤⼩来判断其进⼊队列的先后次序,速度⼤的先进⼊队列,速度⼩的后进⼊队列,从⽽以⼩球在队列中的顺序表⽰⼩球到达的先后次序。位于队头的⼩球⾸先开始运⾏,直到其通过“CPU”,然后将其从队列中移出。每个⼩球在到达就绪队列时会判断⾃⼰是否位于队头,若是则开始(或继续)向前运动
直到通
过“CPU”,然后从队列中移出;若不是则在“就绪队列”中等待,直到队列为空,这时意味着所以的⼩球都已经通过了“CPU”,之后CPU空闲,模拟结束。
4.主要代码及解释如下所⽰:
(1)⾸先需要定义⼀个⼩球类Ball,其包含x、y和speed三个属性值,分别表⽰⼩球在panel中的横坐标、纵坐标和运动的速度。
class Ball{
int x;
int y;
int speed;
public Ball(int x,int y,int speed){
this.x=x;
this.y=y;
this.speed=speed;
}
public int getY(){
return y;
}
public int getX(){
return x;
}
}
(2)定义Panel类,其继承⾃JPanel类,除了需要在其构造函数中将控件加⼊panel外,还需要定义⽤于
改变⼩球坐标的go()⽅法,同时还要重写Panel的paint()⽅法,⽤来根据⼩球的坐标在panel中重绘⼩球。
public void go(int n,Ball ball){
if(ball_x[n]<400){
ball_x[n]=ball_x[n]+ball_speed[n]*5;
ball.x=ball_x[n];
}
else{
if(BallQueue.peek()==ball){
if(ball.x<830){
ball_x[n]+=30;
ball.x = ball_x[n];
ball.y=270;
}
else if(ball.x<980){
ball_x[n]+=10;
ball.x = ball_x[n];
label.setText("进程"+(n+1)+"正在使⽤CPU");
}
else{
label.setText("CPU空闲,即将调度下⼀个进程");
}
}
}
if(BallQueue.size()==0){
java开发可视化界面label.setText("执⾏结束,CPU空闲");
}
}
重写repaint()⽅法,并在其中根据“CUP”的使⽤情况显⽰相应的提⽰信息:
public void paint(Graphics g){
super.paint(g);
g.setColor(Color.pink);
g.fillRect(390,20,70,500);
g.setColor(Color.GREEN);
g.fillRect(460,260,370,70);
g.setColor(Color.white);
g.setFont(new Font("宋体",Font.BOLD,25));
g.drawString("就",410,50);
g.drawString("绪",410,80);
g.drawString("队",410,110);
g.drawString("列",410,140);
g.setColor(Color.BLUE);
g.fillRect(830,220,150,150);
g.setColor(Color.black);
g.setFont(new Font("宋体",Font.BOLD,50));
g.drawString("CPU",870,310);
g.an);
g.X(),Y(),50,50);
g.setFont(new Font("宋体",Font.BOLD,15));
g.drawString("进程1",X(),(Y()-20));
g.setColor(Color.ORANGE);
g.X(),Y(),50,50);
g.drawString("进程⼆",X(),(Y()-20));
g.setColor(Color.black);
g.X(),Y(),50,50);
g.drawString("进程三",X(),(Y()-20));
g.ay);
g.X(),Y(),50,50);
g.drawString("进程四",X(),(Y()-20));
}
(3)定义线程类BallThread,其继承⾃Thread,每⼀个⼩球的运动开启⼀个线程。该类的⼀个属性值为Panel类型。BallThread对象通过Panel中的go()⽅法改变⼩球的坐标,通过Panel中的paint()⽅法来绘制⼩球的位置。
class BallThread extends Thread{
public Panel panel;
public Ball ball;
public int n;
public BallThread(Panel panel,Ball ball,int n){
this.panel=panel;
this.ball=ball;
this.n=n;
}
public void run(){
while(true){
<(n,ball);
try{
sleep(80);
}catch(Exception e){
e.printStackTrace();
}
}
}
}
附录程序清单
fcfs.java清单:
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.LinkedList;
import java.util.LinkedList;
import java.util.Queue;
public class fcfs {
public static void main(String[] arg){
ThreadFrame threadFrame=new ThreadFrame();
threadFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
class ThreadFrame extends JFrame {
public Panel panel =new Panel();
public Container container;
public ThreadFrame(){
setTitle("模拟fcfs进程调度算法");
setSize(1150,600);
setLocationRelativeTo(null);
container =getContentPane();
container.add(panel);
setVisible(true);
}
}
class Panel extends JPanel{
public JButton btn_start=new JButton("开始");
public JButton btn_close=new JButton("退出");
public JButton btn_renew=new JButton("重置并开始");
public Ball ball1;
public Ball ball2;
public Ball ball3;
public Ball ball4;
public BallThread b1;
public BallThread b2;
public BallThread b3;
public BallThread b4;
public JLabel label=new JLabel("CPU空闲");
//public JLabel label2=new JLabel("执⾏顺序:");//显⽰本次模拟的进程执⾏的顺序public int[] ball_speed=new int[4];
public int[] ball_x=new int[4];
public static Queue<Ball> BallQueue =new LinkedList<Ball>();//存放⼩球的队列public Panel(){
setLayout(null);
setSize(1000,600);
btn_start.setBounds(550,470,100,30);
btn_close.setBounds(800,470,100,30);
btn_renew.setBounds(670,470,100,30);
label.setBounds(800,150,450,50);
label.setFont(new Font("宋体",Font.BOLD,25));
//label2.setBounds(500,50,500,30);
//label2.setFont(new Font("宋体",Font.BOLD,20));
add(btn_start);
add(btn_close);
add(btn_renew);
add(label);
//add(label2);
for(int i=0;i<4;i++)
{
ball_speed[i]=(int)(Math.random()*5)+1;
for(int j=0;j<i;j++){
if(ball_speed[i]==ball_speed[j]){
ball_speed[i]=0;
i=i-1;
break;
}
}
}
ball1=new Ball(10,100,ball_speed[0]);
ball2=new Ball(10,200,ball_speed[1]);
ball3=new Ball(10,300,ball_speed[2]);
ball3=new Ball(10,300,ball_speed[2]);
ball4=new Ball(10,400,ball_speed[3]);
b1=new BallThread(this,ball1,0);
b2=new BallThread(this,ball2,1);
b3=new BallThread(this,ball3,2);
b4=new BallThread(this,ball4,3);
if(ball1.speed>ball2.speed&&ball1.speed>ball3.speed&&ball1.speed>ball4.speed){
BallQueue.offer(ball1);
if(ball2.speed>ball3.speed&&ball2.speed>ball4.speed){
BallQueue.offer(ball2);
if(ball3.speed>ball4.speed){
BallQueue.offer(ball3);
BallQueue.offer(ball4);
}
else{
BallQueue.offer(ball4);
BallQueue.offer(ball3);
}
}
else if(ball3.speed>ball2.speed&&ball3.speed>ball4.speed){
BallQueue.offer(ball3);
if(ball2.speed>ball4.speed){
BallQueue.offer(ball2);
BallQueue.offer(ball4);
}
else{
BallQueue.offer(ball4);
BallQueue.offer(ball2);
}
}
else if(ball4.speed>ball2.speed&&ball4.speed>ball3.speed){
BallQueue.offer(ball4);
if(ball2.speed>ball3.speed){
BallQueue.offer(ball2);
BallQueue.offer(ball3);
}
else{
BallQueue.offer(ball3);
BallQueue.offer(ball2);
}
}
}
else if(ball2.speed>ball1.speed&&ball2.speed>ball3.speed&&ball2.speed>ball4.speed){ BallQueue.offer(ball2);
if(ball1.speed>ball3.speed&&ball1.speed>ball4.speed){
BallQueue.offer(ball1);
if(ball3.speed>ball4.speed){
BallQueue.offer(ball3);
BallQueue.offer(ball4);
}
else{
BallQueue.offer(ball4);
BallQueue.offer(ball3);
}
}
else if(ball3.speed>ball1.speed&&ball3.speed>ball4.speed){
BallQueue.offer(ball3);
if(ball1.speed>ball4.speed){
BallQueue.offer(ball1);
BallQueue.offer(ball4);
}
else{
BallQueue.offer(ball4);
BallQueue.offer(ball1);
}
}
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论