当前位置:文档之家› 并行计算实验报告一

并行计算实验报告一

江苏科技大学计算机科学与工程学院实验报告实验名称:Java多线程编程学号:姓名:班级:完成日期:2014年04月22日1.1 实验目的(1) 掌握多线程编程的特点;(2) 了解线程的调度和执行过程;(3)掌握资源共享访问的实现方法。

1.2 知识要点1.2.1线程的概念(1)线程是程序中的一个执行流,多线程则指多个执行流;(2)线程是比进程更小的执行单位,一个进程包括多个线程;(3)Java语言中线程包括3部分:虚拟CPU、该CPU执行的代码及代码所操作的数据。

(4)Java代码可以为不同线程共享,数据也可以为不同线程共享;1.2.2 线程的创建(1) 方式1:实现Runnable接口Thread类使用一个实现Runnable接口的实例对象作为其构造方法的参数,该对象提供了run方法,启动Thread将执行该run方法;(2)方式2:继承Thread类重写Thread类的run方法;1.2.3 线程的调度(1) 线程的优先级●取值范围1~10,在Thread类提供了3个常量,MIN_PRIORITY=1、MAX_PRIORITY=10、NORM_PRIORITY=5;●用setPriority()设置线程优先级,用getPriority()获取线程优先级;●子线程继承父线程的优先级,主线程具有正常优先级。

(2) 线程的调度:采用抢占式调度策略,高优先级的线程优先执行,在Java中,系统按照优先级的级别设置不同的等待队列。

1.2.4 线程的状态与生命周期说明:新创建的线程处于“新建状态”,必须通过执行start()方法,让其进入到“就绪状态”,处于就绪状态的线程才有机会得到调度执行。

线程在运行时也可能因资源等待或主动睡眠而放弃运行,进入“阻塞状态”,线程执行完毕,或主动执行stop方法将进入“终止状态”。

1.2.5 线程的同步--解决资源访问冲突问题(1) 对象的加锁所有被共享访问的数据及访问代码必须作为临界区,用synchronized加锁。

对象的同步代码的执行过程如图14-2所示。

synchronized关键字的使用方法有两种:●用在对象前面限制一段代码的执行,表示执行该段代码必须取得对象锁。

●在方法前面,表示该方法为同步方法,执行该方法必须取得对象锁。

(2) wait()和notify()方法用于解决多线程中对资源的访问控制问题。

●wait()方法:释放对象锁,将线程进入等待唤醒队列;●notify()方法:唤醒等待资源锁的线程,让其进入对象锁的获取等待队列。

(3)避免死锁指多个线程相互等待对方释放持有的锁,并且在得到对方锁之前不会释放自己的锁。

1.3 上机测试下列程序样例1:利用多线程编程编写一个龟兔赛跑程序。

乌龟:速度慢,休息时间短;兔子:速度快,休息时间长;【参考程序1】字符方式下实现方案class Animal extends Thread {int speed; //速度public Animal( String str,int speed) {super(str); //线程名用动物名代表this.speed=speed;}public void run() {int distance=0;int sleepTime;while (distance<=1000) {System.out.println(getName()+"is at"+distance);try {distance+=speed; //每次跑的距离简单用速度计算sleepTime=(int)( speed+Math.random()*speed); //速度快休息时间要长sleep(sleepTime);} catch (InterruptedException e) {}}}}public class Race {public static void main(String arg[]) {Animal a1, a2;a1=new Animal("rabit",100);a2=new Animal("turtle",20);a2.setPriority(Thread.MAX_PRIORITY); //让乌龟的运行优先级更高a1.start();a2.start();}}【编程技巧】(1)速度快,跑的距离增加也快,这里简单地将速度加到距离上,未考虑跑的时间;(2)为了让乌龟得到更多的运行机会,采取两项措施,一让线程的睡眠时间与速度成正比,二是让乌龟得到更高的优先级。

【参考程序2】—图形方式下,图14-3为程序的运行演示。

public class runner extends Applet implements Runnable {int BeginX=10,EndX=200; //起点和终点的x坐标int RabbitX = BeginX,RabbitY=100; //兔子的起点int TortoiseX=BeginX, TortoiseY=200; //乌龟的起点int RabbitRestTime=800,TortoiseRestTime=50; //各自休息时间int RabbitSpeed=15,TortoiseSpeed=1; //各自速度int state=0; //比赛状态, 0代表比赛进行中,1代表兔子赢,2代表乌龟赢Thread rabbit;Thread tortoise;public void init() {rabbit = new Thread(this,"rabbit"); //创建名为rabit的线程tortoise = new Thread(this,"tortoise"); //创建名为tortoise的线程}public void paint(Graphics g) {g.drawString("龟",TortoiseX,TortoiseY);g.drawString("兔",RabbitX,RabbitY);g.setColor(Color.red);for(int j=70;j<=230;j+=10) g.drawString("|",EndX+8,j); //绘制终点线g.setColor(Color.black);if(state==1) g.drawString("兔子赢了!!",250,300);else if(state==2) g.drawString("乌龟赢了!!",250,300);}public void start() {rabbit.start();tortoise.start();}public void run() {String currentRunning;while (state==0) {currentRunning=Thread.currentThread().getName();//得到当前线程的名程if(currentRunning.equals("rabbit")) { //是兔子try{Thread.sleep((int)(Math.random()*RabbitRestTime));}catch(InterruptedException e){ }RabbitX+=RabbitSpeed;if(RabbitX>EndX) RabbitX=EndX;}else if(currentRunning.equals("tortoise")) { //是乌龟try{Thread.sleep((int)(Math.random()*TortoiseRestTime));}catch(InterruptedException e){ }TortoiseX+=TortoiseSpeed;if(TortoiseX > EndX) TortoiseX=EndX;}if (RabbitX == EndX) state=1;else if ( TortoiseX == EndX) state=2;repaint();}}}【编程技巧】(1)创建两个代表兔子和乌龟的线程,根据线程名决定各自的速度和休息时间。

(2)根据是否到达终点决定state值的变化;(3)线程的run方法内的循环条件是state值为0。

样例2:编写选号程序,在窗体中安排6个标签,每个标签上显示0~9之间的一位数字,每位数字用一个线程控制其变化,点击“停止”按钮则所有标签数字停止变化。

【参考程序】import java.awt.*;import java.awt.event.*;public class MyFrame extends Frame{MyLabel x[]=new MyLabel[6]; //安排6个标签,每个标签显示1个数字Button control;public MyFrame(String title) {super(title);Panel disp=new Panel();disp.setLayout(new FlowLayout());for (int i=0;i<6;i++ ) {x[i]=new MyLabel();disp.add(x[i]);new Thread(x[i]).start();}add("Center",disp);control=new Button("停止");add("North",control);pack();setVisible(true);control.addActionListener(new ActionListener(){public void actionPerformed(ActionEvent e) {for(int i=0;i<6;i++)x[i].stop=true;}});}public static void main(String args[]) {new MyFrame("Test");}class MyLabel extends Label implements Runnable{int value;boolean stop=false;public MyLabel(){super("number");value=0;}public void run() {for (; ; ) {value=(int)(Math.random()*10); //产生一个0到9的数字setText(Integer.toString(value));try {Thread.sleep(500);}catch (InterruptedException e) { }if (stop) //停止标记为true,退出循环,结束运行break;}}}}【编程技巧】(1) 将每个标签定义为线程方式运行,在运行中利用随机数产生数字显示。

相关主题