实验五 多线程程序设计(汽院含答案)

2020-04-14 01:03

实验五 多线程程序设计

实验目的

1. 掌握Java语言中多线程编程的基本方法 2. 掌握Runnable接口实现多线程的方法 3. 掌握Thread类实现多线程的用法

实验导读

1. 进程和线程的概念

进程是程序一次动态执行的过程,对应从代码加载、执行到执行结束这样一个完整的过程,也是进程自身从产生、发展到消亡的过程。

线程是比进程更小的执行单元,一个进程在执行过程中,可以产生多个线程。每个线程都有自身的产生、执行和消亡的过程。

2. 线程的状态与生命周期

? 新建:当一个Thread类或其子类的对象被声明并创建时,新生的线程对象处于新建状态。此时它

已经有了相应的内存空间和其他资源。

? 运行:线程创建之后就具备了运行的条件,一旦轮到它来享用CPU资源时,即JVM将CPU使用权

切换给该线程时,此线程的就可以脱离创建它的主线程独立开始自己的生命周期了(即run方法执行的过程)。

? 中断:有4种原因的中断,CPU资源从当前线程切换给其他线程、执行了sleep(int millsecond)方法、

执行了wait()方法、进入阻塞状态 。 ? 死亡:run方法结束。

3. 线程的创建

在Java语言中,与线程支持密切相关的是java.lang.Thread类和java.lang.Runnable接口。Runnable接口定义很简单,只有一个run方法。任何一个类如果希望自己的实例能够以线程的形式执行,都可以来实现Runnable接口。

继承Thread类和实现Runnable接口,都可以用来创建Thread对象,效果上并没有什么不同。继承Thread类的方法很明显的缺点就是这个类不能再继承其他的类了,而实现Runnable接口不会有这个麻烦。

另外,在继承Thread类的代码中,this其实就是指当前正在运行的线程对象,如果使用实现Runnable接口的方式,要得到当前正在执行的线程,需要使用Thread.currentThread()方法。

线程创建后仅仅是占有了内存资源,在JVM管理的线程中还没有这个线程,此线程必须调用start()方法(从父类继承的方法)通知JVM,这样JVM就会知道又有一个新一个线程排队等候切换了。

注意:多次启动一个线程,或者启动一个已经运行的线程对象是非法的,会抛出IllegalThreadStateException异常对象。

4. 线程的优先级

同一时刻在等待队列中的线程会有很多个,它们各自任务的重要性有所不同。为了加以区分,使工作安排和资源分配时间更为合理,每个线程可以被赋予不同的优先级,让任务比较急的线程拥有更高的优先级,从而更快地进入执行状态。

Java中提供了10个等级的线程优先级,最低为Thread.MIN_PRIORITY=1,最高为

Thread.MAX_PRIORITY=10,默认优先级为Thread.NORM_PRIORITY=5。

使用Thread类中的setPriority(int)方法可以为线程指定优先级。

5. 线程的常用方法 ? start() 方法:

线程调用该方法将启动线程,使之从新建状态进入就绪队列排队,一旦轮到它来享用CPU资源时,就可以脱离创建它的线程独立开始自己的生命周期了。

? run()方法:

Thread类的run()方法与Runnable接口中的run()方法的功能和作用相同,都用来定义线程对象被调度之后所执行的操作,都是系统自动调用而用户程序不得引用的方法。系统的Thread类中,run()方法没有具体内容,所以用户程序需要创建自己的Thread类的子类,并重写run()方法来覆盖原来的run()方法。当run方法执行完毕,线程就变成死亡状态。

? sleep(int millsecond) 方法:

现程占有CPU期间,执行sleep方法来使自己放弃CPU资源,休眠一段时间。休眠时间的长短由sleep方法的参数决定,millsecond是毫秒为单位的休眠时间。如果线程在休眠时被打断,JVM就抛出InterruptedException异常。因此,必须在try~catch语句块中调用sleep方法。

? isAlive() 方法:

线程处于“新建”状态时,线程调用isAlive()方法返回false。当一个线程调用start()方法,并占有CUP资源后,该线程的run方法就开始运行,在线程的run方法结束之前,即没有进入死亡状态之前,线程调用isAlive()方法返回true。当线程进入“死亡”状态后(实体内存被释放),线程仍可以调用方法isAlive(),这时返回的值是false。

一个已经运行的线程在没有进入死亡状态时,不要再给线程分配实体,由于线程只能引用最后分配的实体,先前的实体就会成为“垃圾”,并且不会被垃圾收集机收集掉。

? currentThread() 方法:

currentThread()方法是Thread类中的类方法,可以用类名调用,该方法返回当前正在使用CPU资源的线程。

? interrupt() 方法: intertupt方法经常用来“吵醒”休眠的线程。当一些线程调用sleep方法处于休眠状态时,一个占有CPU资源的线程可以让休眠的线程调用interrupt 方法“吵醒”自己。

6. 线程的同步

线程同步是指几个线程都需要调用一个同步方法(使用关键字synchronized修饰的方法) 。 当一个线程A使用一个synchronized修饰的方法时,其他线程想使用这个方法时就必须等待,直到线程A 使用完该方法 (除非线程A使用wait主动让出CPU资源)。

一个线程在使用的同步方法中时,可能根据问题的需要,必须使用wait()方法使本线程等待,暂时让出CPU的使用权,并允许其它线程使用这个同步方法。其它线程如果在使用这个同步方法时如果不需要等待,那么它用完这个同步方法的同时,应当执行notifyAll()方法通知所有的由于使用这个同步方法而处于等待的线程结束等待。

? 挂起:

有时候两个线程并不是同步的,即不涉及都需要调用一个同步方法,但线程也可能需要暂时的挂起。所谓挂起一个线程就是让线程暂时让出CPU的使用权限,暂时停止执行,但停止执行的持续时间不确定,因此不能使用sleep方法暂停线程。挂起一个线程需使用wait方法,即让准备挂起的线程调用 wait 方法,主动让出CPU的使用权限. ? 恢复:

为了恢复该线程,其它线程在占有CUP资源期间,让挂起的线程的目标对象执行notifyAll()方法,使得挂起的线程继续执行;如果线程没有目标对象,为了恢复该线程,其它线程在占有CUP资源期间,

让挂起的线程调用notifyAll()方法,使挂起的线程继续执行。

实验内容

1. 汉字识别程序

编写一个Java应用程序,在主线程中再创建一个Frame类型的窗口,在该窗口中再创建一个线程giveWord。线程giveWord每隔6秒钟给出一个汉字,用户使用一种汉字输入法将该汉字输入到文本框中。请按模板要求,将代码补充完整。

WordThread.java

import java.awt.*;

public class WordThread extends Thread { char word; Label com;

WordThread(Label com) { this.com = com; }

public void run() { while (true) {

word = (char) (Math.random()*(29968-19968)+19968); System.out.println(word); com.setText(\ + word); try { }

ThreadFrame.java

public class ThreadFrame extends Frame implements ActionListener { Label wordLabel; Button button;

TextField inputText, scoreText;

【补充代码】 // 用WordThread声明一个giveWord对象 int score = 0;

ThreadFrame() {

wordLabel = new Label(\, Label.CENTER);

wordLabel.setFont(new Font(\, Font.BOLD, 72));

button = new Button(\开始\); inputText = new TextField(3); scoreText = new TextField(5); scoreText.setEditable(false);

【补充代码】 // 调用sleep方法使得线程中断6000豪秒 } catch (InterruptedException e) {} } }

【补充代码】// 创建giveWord,将wordLabel传递给WordThread构造方法的参数 button.addActionListener(this); inputText.addActionListener(this); add(button, BorderLayout.NORTH);

add(wordLabel, BorderLayout.CENTER);

Panel southP = new Panel();

southP.add(new Label(\输入标签所显示的汉字后回车:\)); southP.add(inputText); southP.add(scoreText);

add(southP, BorderLayout.SOUTH); setBounds(100, 100, 350, 180); setVisible(true); validate();

addWindowListener(new WindowAdapter() {

public void windowClosing(WindowEvent e) { System.exit(0); } }); }

public void actionPerformed(ActionEvent e) { if (e.getSource() == button) {

if (!(【补充代码】)) // giveWord调用方法isAlive() {

giveWord = new WordThread(wordLabel); }

try { 【补充代码】// giveWord调用方法start() } catch (Exception exe) { }

} else if (e.getSource() == inputText) {

if (inputText.getText().equals(wordLabel.getText())) { score++;

}

scoreText.setText(\得分:\ + score); inputText.setText(null); } }

}

WordThread.java

public class ThreadWordMainClass {

public static void main(String args[]) { new ThreadFrame(); }

} 答案代码: WordThread.java import java.awt.*; public class WordThread extends Thread { char word; Label com; WordThread(Label com) { this.com = com; } public void run() { while (true) { word = (char) (Math.random()*(29968-19968)+19968); System.out.println(word); com.setText(\ + word); try { sleep(6000); // 调用sleep方法使得线程中断6000豪秒 } catch (InterruptedException e) {} } } } ThreadFrame.java public class ThreadFrame extends Frame implements ActionListener { Label wordLabel; Button button; TextField inputText, scoreText; WordThread giveWord; // 用WordThread声明一个giveWord对象 int score = 0; ThreadFrame() { wordLabel = new Label(\, Label.CENTER); wordLabel.setFont(new Font(\, Font.BOLD, 72)); button = new Button(\开始\); inputText = new TextField(3); scoreText = new TextField(5); scoreText.setEditable(false); giveWord=new WordThread(wordLabel); // 创建giveWord,将wordLabel传递给WordThread构造方法的参数 button.addActionListener(this);


实验五 多线程程序设计(汽院含答案).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:stm32移植rt-thread

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: