重庆交通大学综合性设计性实验报告实验项目名称:进程调度(先来先服务)实验项目性质: JAVA多线程实验所属课程: JAVA程序设计实验室(中心):语音大楼 8 楼 801班级:软件专业 2012级2班姓名:尚亚*学号: 631206050216指导教师:杨实验完成时间: 2014 年 11 月 25 日一、实验目的1、理解程序、线程和进程的概念;2、理解多线程的概念;3、掌握线程的各种状态;4、熟练使用Thread类创建线程;5、熟练使用线程各种方法;6、掌握线程的调度及线程同步的实现原理。
二、实验内容及要求进程调度是处理机管理的核心内容。
本实验要求采用最高优先数优先的调度算法(即把处理机分配给优先数最高的进程)和先来先服务算法编写和调试一个简单的进程调度程序。
通过本实验可以加深理解有关进程控制块、进程队列的概念。
并体会了优先数和先来先服务调度算法的具体实施办法。
用JA V A语言编写和调试一个进程调度程序,以加深对进程的概念及进程调度算法的理解。
做一个能够直观体现多个进程时,CPU 是怎样调度就绪队列中的进程(按照先来先服务的原则)。
三、实验设备PC机,windows7,eclipse。
四、设计方案㈠设计主要思想(1)要模拟进程的调度算法,必须先体现处进程及系统资源。
(2)要体现先来先服务的算法,就必须表现出当有一个进程进入CPU时其他进程不能进入,并在就绪队列中排队。
本实验建立了四个圆移动的线程表示作业调度,用圆在表示就绪队列的方框中停留表示进程在就绪队列中排队。
(3)当有一个圆移动到表示CPU的范围内时,让其它线程在就绪队列中排队,当CPU内无进程时,先来的圆先移动,以表示CPU 对进程的调度。
㈡设计的主要步骤(1)建立四个不同颜色的圆移动的线程,表示对四个进程的调度。
(2)当有一个表示进程的圆到达表示CPU范围内时,通过让其它几个圆停留在表示就绪队列的方框范围内,表示进程在就绪队列中排成队列。
(3)当第一个先到达的进程释放CPU,在排成队列的几个圆中选择先到达的圆,使其移动表示对先来的进程进行调度,直到所有的圆移动完毕。
五、主要代码import java.awt.Font;import java.awt.event.*;import java.awt.*;import javax.swing.*;public class DoubleBuffer extends Frame //主类继承Frame类{ private JButton button1;private Image iBuffer,iBuffer1;private Graphics gBuffer1,gBuffer2,gBuffer3,gBuffer4,gBuffer5,gBuffer6;public paintThread pT1;//绘图线程public paintThread pT2;//绘图线程public paintThread pT3;//绘图线程public paintThread pT4;//绘图线程public int x1=100,y1=100;//小圆横、纵坐标public int x2=100,y2=170;//小圆横、纵坐标public int x3=100,y3=240;//小圆横、纵坐标public int x4=100,y4=310;//小圆横、纵坐标public int a=1;public int b=2;public int c=3;public int d=4;public DoubleBuffer()//构造函数{super("Java实现调度模拟");this.setResizable(false); //窗体不可最大化this.setSize(750,470); //设置窗口的首选大小this.setVisible(true); //显示窗口button1= new JButton("运行");pT1=new paintThread(this,1);pT2=new paintThread(this,2);pT3=new paintThread(this,3);pT4=new paintThread(this,4);button1.setLocation(100, 415);button1.setSize(90, 40);add(button1);button1.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) { // TODO Auto-generated method stubx1=100;y1=100;//小圆横、纵坐标x2=100;y2=170;//小圆横、纵坐标x3=100;y3=240;//小圆横、纵坐标x4=100;y4=310;//小圆横、纵坐标a=1;b=2;c=3;d=4;pT1.start(); //绘图线程启动pT2.start(); //绘图线程启动pT3.start(); //绘图线程启动pT4.start(); //绘图线程启动}});}public void paint(Graphics scr) //重载绘图函数{scr.setColor(Color.RED); //设置小圆颜色Font font1 = new Font("宋体", Font.BOLD, 30);scr.setFont(font1);scr.drawString("CPU", 580, 235);Font font = new Font("宋体", Font.BOLD, 20);scr.setFont(font);scr.drawString("线程一", 250, 135);scr.fillOval(x1,y1,60,60); //绘制小圆scr.setColor(Color.BLUE); //设置小圆颜色//Font font = new Font("宋体", Font.BOLD, 20);//scr.setFont(font);scr.drawString("线程二", 250, 205);scr.fillOval(x2,y2,60,60); //绘制小圆scr.setColor(Color.YELLOW); //设置小圆颜色//Font font = new Font("宋体", Font.BOLD, 20);//scr.setFont(font);scr.drawString("线程三", 250, 275);scr.fillOval(x3,y3,60,60); //绘制小圆scr.setColor(Color.PINK); //设置小圆颜色//Font font = new Font("宋体", Font.BOLD, 20);//scr.setFont(font);scr.drawString("线程四", 250, 345);scr.fillOval(x4,y4,60,60); //绘制小圆//button1.repaint();}public void update(Graphics scr){if(iBuffer1==null){iBuffer1=createImage(670,400);gBuffer1=iBuffer1.getGraphics();}gBuffer1.setColor(Color.BLACK);gBuffer1.fillRect(100,100,340,60);gBuffer1.setColor(Color.BLACK);gBuffer1.fillRect(100,170,340,60);gBuffer1.setColor(Color.BLACK);gBuffer1.fillRect(100,240,340,60);gBuffer1.setColor(Color.BLACK);gBuffer1.fillRect(100,310,340,60);gBuffer1.setColor(Color.MAGENTA);gBuffer1.fillRect(440,100,60,270);gBuffer1.setColor(Color.GREEN);gBuffer1.fillRect(500,205,170,60);paint(gBuffer1);scr.drawImage(iBuffer1,0,0,this);}public static void main(String[] args){DoubleBuffer DB=new DoubleBuffer();//创建主类的对象DB.addWindowListener(new WindowAdapter() //添加窗口关闭处理函数{public void windowClosing(WindowEvent e){System.exit(0);}});}}class paintThread extends Thread//绘图线程类{DoubleBuffer DB;int s;public paintThread(DoubleBuffer DB,int s) //构造函数{this.DB=DB;this.s=s;}public void run()//重载run()函数{while(true)//线程中的无限循环{DB.repaint();//窗口重绘if(s==1){if(DB.x1<440){DB.x1++; //修改小圆的横坐标try{sleep(20); //线程休眠20ms}catch(InterruptedException e){}}else if(DB.a==1&&DB.b==0&&DB.x1<670) {DB.y1=205;if(DB.x1==440)DB.x1=DB.x1+40;DB.x1++; //修改小圆的横坐标try{sleep(15); //线程休眠15ms}catch(InterruptedException e){}}}if(s==2){if(DB.x2<440){DB.x2++; //修改小圆的横坐标try{sleep(13); //线程休眠13ms}catch(InterruptedException e){}}elseif(DB.a==1&&DB.b==2&&DB.c==3&&DB.d==0&&DB.x2<670){DB.y2=205;if(DB.x2==340)DB.x2=DB.x2+40;DB.x2++; //修改小圆的横坐标try{sleep(15); //线程休眠15ms}catch(InterruptedException e){}}else if(DB.d==0)DB.c=0;}if(s==3){if(DB.x3<440){DB.x3++; //修改小圆的横坐标try{sleep(16); //线程休眠16ms}catch(InterruptedException e){}}else if(DB.a==1&&DB.b==2&&DB.c==0&&DB.x3<670){DB.y3=205;if(DB.x3==340)DB.x3=DB.x3+40;DB.x3++; //修改小圆的横坐标try{sleep(15); //线程休眠15ms}catch(InterruptedException e){}}else if(DB.d==0&&DB.c==0)DB.b=0;}if(s==4){if(DB.x4<440){DB.x4++; //修改小圆的横坐标try{sleep(8); //线程休眠8ms}catch(InterruptedException e){}}elseif(DB.a==1&&DB.b==2&&DB.c==3&&DB.d==4&&DB.x4<670){DB.y4=205;if(DB.x4==340)DB.x4=DB.x4+40;DB.x4++; //修改小圆的横坐标try{sleep(15); //线程休眠15ms}catch(InterruptedException e){}}elseDB.d=0;}//DB.repaint();//窗口重绘}}}六、测试结果及说明1、四个圆表示四个线程:2、当有一个进程进入CPU时,其他进程在就绪队列中排队:3、当一个进程不在独占CPU时,先到达的进程先得到CPU资源:七、实验体会通过这次实验,我对多线程有了更进一步的理解,对调度的算法的实现有了更深一步的认识,了解了调度算法的原理及使用调度算法的意义,同时明白了调度算法对于整个操作系统资源的利用及系统的吞吐量都有很大影响,对操作系统的性能也有很大的影响。