面向对象程序设计-java语言09

上传人:第*** 文档编号:48884011 上传时间:2018-07-21 格式:PPT 页数:40 大小:226.50KB
返回 下载 相关 举报
面向对象程序设计-java语言09_第1页
第1页 / 共40页
面向对象程序设计-java语言09_第2页
第2页 / 共40页
面向对象程序设计-java语言09_第3页
第3页 / 共40页
面向对象程序设计-java语言09_第4页
第4页 / 共40页
面向对象程序设计-java语言09_第5页
第5页 / 共40页
点击查看更多>>
资源描述

《面向对象程序设计-java语言09》由会员分享,可在线阅读,更多相关《面向对象程序设计-java语言09(40页珍藏版)》请在金锄头文库上搜索。

1、第9章 多线程线程本是操作系统的一个重要概念。多线程是指程 序中同时存在着多个执行体,它们按几条不同的执 行路线共同工作,独立完成各自的功能而互不干扰 。以往我们所开发的程序,大多是单线程的,即一 个程序只有一条从头至尾的执行路线。而现在在只 有一个CPU的个人计算机上,我们在听着美妙音乐 的同时,还可用键盘输入文本、用打印机打印文件 、从网络上接收电子邮件等,这便是计算机操作系 统为我们提供的多线程并发机制的功劳。大多数程序设计语言并不提供这种并发机制, 它们一般只提供几种简单的控制结构。利用这 些控制结构一次只能执行一个动作,只有前一 个动作完成后,才能开始执行下一个动作。 Java语言提

2、供了多线程机制,可在应用程序中 加入多个线程,每个线程都可完成某一部分独 立的功能,并且可以与其他线程并发执行,从 而在应用程序中实现多线程并发操作。本章主要内容9.1 Java的多线程机制 9.2 通过继承Thread类实现多线程 9.3 线程等待 9.4 线程同步 9.5 线程的优先级9.1 Java的多线程机制多线程机制是Java语言的又一重要特征, 使用多线程技术可以使系统同时运行多个 执行体,这样就可以减少程序的响应时间 ,提高计算机资源的使用效率。正确使用 多线程技术可提高整个应用系统的性能。线程的生命周期 每个Java程序都有一个默认的主线程 ,对于Application类型的程

3、序来说, 主线程是main()方法执行的线程。对 于Applet,主线程指挥浏览器加载并 执行Java小程序。要想实现多线程, 必须在主线程中创建新的线程对象。Java语言使用Thread类及其子类的对 象来表示线程,新建的线程在它的一 个完整的生命周期中通常要经历新生 、就绪、运行、阻塞和死亡等5种状态 ,这5种状态之间的转换关系和转换条 件如图9-1所示。resumewaitsleep挂起I/O 完成notify或 notifyAll超过睡眠间隔stop或 完成I/O申请超过配额分配CPUstart就绪运行等待睡眠死亡阻塞新建suspend图9-1 线程的生命周期1新生状态 当用new关键

4、字和某线程类的构造方 法创建一个线程对象后,这个线程对 象处于新生状态,此时它已经有了相 应的内存空间,并已被初始化。处于 该状态的线程可通过调用start()方法进 入就绪状态。2就绪状态 处于就绪状态的线程已经具备了运行 的条件,但尚未分配到CPU资源,因 而它将进入线程队列排队,等待系统 为它分配CPU。一旦获得CPU资源, 则该线程就进入运行状态,并自动地 调用自己的run方法。此时,它脱离创 建它的主线程,独立开始了自己的生 命周期。3运行状态进入运行状态的线程正在执行自己的 run方法中的代码。若遇到下列情况之 一,则将终止run方法的执行。 (1)终止操作。调用当前线程的stop

5、() 方法或destroy()方法进入死亡状态。(2)等待操作。调用当前线程的 join(millis)方法或wait(millis)方法进入阻塞 状态。当线程进入阻塞状态时,在millis毫 秒内可由其他线程调用notify()或 notifyAll()方法将其唤醒,进入就绪状态。 在millis毫秒内若不唤醒则须等待到当前线 程结束。 (3)睡眠操作。调用sleep(millis)方法来 实现。当前线程停止执行时,则处于阻塞 状态,睡眠millis毫秒之后重新进入就绪状 态。(4)挂起操作。通过调用suspend()方法 来实现。将当前线程挂起,进入阻塞状态 ,之后当其他线程调用当前线程的

6、 resume()方法后,才能使其进入就绪状态 。 (5)退让操作。通过调用yield()方法来实 现。当存在和当前线程相同优先级的线程 时,当前线程放弃执行,退让给其他相同 优先级的线程,进入就绪状态,否则继续 执行。(6)当前线程要求I/O时,则进入阻塞 状态。 (7)若分配给当前线程的时间片用完 时,当前线程进入就绪状态。当前线程 的run方法执行完,则线程进入死亡状 态。 4阻塞状态一个正在执行的线程在某些特殊情况 下,如执行了suspend、join或sleep方 法,或等待I/O设备的使用权,将让出 CPU并暂时中止自己的执行,进入阻 塞状态。阻塞时它不能进入就绪队列 ,只有当引起

7、阻塞的原因被消除时, 线程才可以转入就绪状态,重新进到 线程队列中排队等待CPU资源,以便 从原来终止处开始继续运行。5死亡状态处于死亡状态的线程将永远不再执行 。线程死亡有两个原因:一是正常运 行的线程完成了它的全部工作;另一 则是线程被提前强制性地终止,例如 ,通过执行stop或destroy方法来终止 线程。 多线程的实现方法 在Java中,创建线程的方法有两种: 一种方法是通过创建Thread类的子类 来实现,另一种方法是通过实现 Runnable接口的类来实现。 用创建Thread类的子类或实现 Runnable接口的类来创建线程无本质 区别,但是由于Java语言不支持类的多继承,如

8、果一个类必须要继承另一 个非Thread类,此时只能通过实现 Runnable接口的方式。例如,Applet 程序必须继承Applet类,要实现多线 程只能通过实现Runnable接口的方式 。9.2 通过继承Thread类实现多线程 Thread类 Thread类综合了Java程序中一个 线程需要拥有的属性和方法,主 要包括以下内容。1构造方法 Thread类的构造方法有多个,所对应 的操作有如下3种。 (1)public Thread ():创建一个系统 线程类的对象。 (2)public Thread ( Runnable target ) :在上一个构造方法完成的操作创 建线程对象的基

9、础之上,利用参数对象实现了Runnable接口 的target对象中所定义的run()方法,来 初始化或覆盖新创建的线程对象的run() 方法。 (3)public Thread ( String ThreadName ):在第一个构造方法工作的基础上,为 所创建的线程对象指定一个字符串名称 供以后使用。(4)public Thread (Runnable target, String ThreadName):实现(2)、(3 )两构造方法的功能。 利用构造方法创建新线程对象之后, 这个对象中的有关数据被初始化,从 而进入线程生命周期的第一个状态 新建状态。2线程优先级 Thread类有3个有

10、关线程优先级的静态常 量:MIN_PRIORITY,MAX_PRIORITY ,NORM_PRIORITY。其中 MIN_PRIORITY代表最小优先级,通常 为1;MAX_PRIORITY代表最高优先级 ,通常为10;NORM_PRIORITY代表普 通优先级,默认数值为5。对应一个新建线程,系统会遵循如下 的原则为其指定优先级。 (1)新建线程将继承创建它的父线程 的优先级。父线程是指执行创建新线 程对象语句的线程,它可能是程序的 主线程,也可能是某一个用户自定义 的线程。 (2)一般情况下,主线程具有普通优 先级。另外,用户可以通过调用Thread类的 方法setPriority()来修

11、改系统自动设定 的线程优先级,使之符合程序的特定 需要。 3其他主要方法 (1)启动线程的start()方法:start()方 法将启动线程对象,使之从新建状态转 入就绪状态并进入就绪队列排队。(2)定义线程操作的run()方法: Thread类的run()方法与Runnable接口 中的run()方法的功能和作用相同,都 用来定义线程对象被调度之后所执行的 操作,也都是系统自动调用而用户程序 不得引用的方法。系统的Thread类中, run()方法没有具体内容,所以用户程 序需要创建自己的Thread类的子类,并 定义新的run()方法来覆盖原来的run() 方法。(3)使线程暂时休眠的sl

12、eep()方法: 线程的调度执行是按照其优先级的高 低顺序进行的,当高级线程未完成, 即未死亡时,低级线程没有机会获得 处理器。有时,优先级高的线程需要 优先级低的线程做一些工作来配合它 ,或者优先级高的线程需要完成一些 费时的操作,此时优先级高的线程应 该让出处理器,使优先级低的线程有机会执行。为达到这个目的,优先 级高的线程可以在它的run()方法中调 用sleep()方法来使自己放弃处理器资 源,休眠一段时间。休眠时间的长短 由sleep()方法的参数决定。 sleep(int millsecond ) ; sleep(int millsecond,int nanosecond) ;(4

13、)判断线程是否未消亡的isAlive() 方法:在调用stop()方法终止一个线程 之前,最好先用isAlive()方法检查一下 该线程是否仍然存活,杀死不存在的 线程可能会造成系统错误。 通过继承Thread类实现多线程 通过继承Thread类实现多线程的方法 是首先设计Thread类的子类,然后根 据需要重新设计线程的run()方法,再 使用start()方法启动线程,将执行权转 交给run()方法。 【例9.1】通过继承Thread类实现多 线程。 通过实现Runnable接口实现多线程 通过Runnable接口实现多线程的方法 是首先设计一个实现Runnable接口的 类,然后根据需要

14、重新设计线程的 run()方法,再建立该类对象。以此对 象为参数建立Thread类的对象,通过 该对象调用Thread类的start()方法启动 线程,将执行权转交到run()方法。【例9.2】通过实现Runnable接口实 现多线程。9.3 线程等待Java程序中的线程并发运行,共同争抢 CPU资源。哪个线程抢夺到CPU资源后, 就开始运行。例9.3将演示main()方法线程 和其他线程的并发运行情况。 【例9.3】多个线程并发执行示例 。如果希望一个线程运行结束之后,再 运行其他线程,可以调用join()方法。 例9.4演示了join()方法的功能。 【例9.4】join()在多线程中的使

15、用。9.4 线程同步Java提供了多线程机制,通过多线程的并发运行 可以提高系统资源利用率,改善系统性能。但在 有些情况下,一个线程必须和其他线程合作才能 共同完成任务。线程可以共享内存,利用这个特 点可以在线程之间传递信息。然而如果处理不当 ,对内存空间的共享可能会造成程序运行的不确 定性和产生其他错误。 【例9.5】线程并发引起的不正确性。在Java中,实现同步操作的方法是在 共享内存变量的方法前加synchronized 修饰符。在程序运行过程中,如果某 一线程调用经synchronized修饰的方法 ,在该线程结束此方法的运行之前, 其他所有线程都不能运行该方法,只 有等该线程完成此方

16、法的运行后,其 他线程才能引入该方法的运行。【例9.6】线程的同步示例。9.5 线程的优先级在Java系统中,运行的每个线程都有优先级 。设置优先级是为了在多线程环境中便于系 统对线程进行调度,优先级高的线程将优先 得以运行。Java线程的优先级是一个在1到10 之间的正整数,数值越大,优先级越高,未 设定优先级的线程其优先级取默认值5。Java 线程的优先级设置遵从下述原则。(1)线程创建时,子线程继承父线程的优先级 。 (2)线程创建后,可在程序中通过调用 setPriority()方法改变线程的优先级。 (3)线程的优先级是110之间的正整数,并 用标识符常量MIN_PRIORITY表示优先级为1 ;NORM_PRIORITY表示优先级为5; MAX_PRIORITY表示优先级为10。其他级别 的优先级既可以直接用110之间的正整数来设 置,也可以在标识符常量的基础上加一个常数 ,例如,下面语句将线程优先级设置为8。 setPriority(Thread.NORM_PRIORITY +3); 【例9.7】

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 办公文档 > 其它办公文档

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号