第10章线程ppt课件_第1页
第10章线程ppt课件_第2页
第10章线程ppt课件_第3页
第10章线程ppt课件_第4页
第10章线程ppt课件_第5页
已阅读5页,还剩71页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、电脑基础实例上机系列丛书java程序设计教程清华大学出版社第10章 多线程学习目标 本章要点上机练习 习 题电脑基础实例上机系列丛书java程序设计教程清华大学出版社学习目标 在计算机处理任务时,往往需要操作系统同时处理多个任务,这些任务就由操作系统本身和cpu来控制。有时也需要自己创建多个任务来让系统同时完成,这些用户自己定制的任务都是非常小的程序段,称为线程。本章介绍线程的基本概念和多线程技术,详细讲解线程的创建,如何实现多线程,还介绍线程同步、线程死锁和线程调度等控制技术。电脑基础实例上机系列丛书java程序设计教程清华大学出版社本章要点 线程的生命周期多线程技术线程的创建和实现多线程线

2、程的同步和死锁电脑基础实例上机系列丛书java程序设计教程清华大学出版社多线程技术的基本概念 多线程是java程序的一个重要特征,线程本来是操作系统中的概念,java将这一概念引入到程序设计语言中,让开发人员利用线程机制编写多线程程序,使系统能够同时运行多个执行体,从而加快程序的响应速度,提高电脑资源的利用率。本节主要介绍多线程机制的一些基本概念。电脑基础实例上机系列丛书java程序设计教程清华大学出版社多线程技术的基本概念什么是线程线程的生命周期 多线程技术 电脑基础实例上机系列丛书java程序设计教程清华大学出版社什么是线程线程和进程类似,是一段完成特定功能的代码。线程是程序中单个程序的控

3、制流,也是一个进程内的基本调度单位。线程和进程一样拥有独立的执行控制,并由操作系统负责调度。 电脑基础实例上机系列丛书java程序设计教程清华大学出版社什么是线程同一个进程可以包含多个线程,这些线程共享属于该进程的一块内存空间和一组系统资源,而线程自身的数据通常只有cpu的寄存器数据,以及一个供程序执行时使用的堆栈,系统在产生一个线程,或者在各个线程之间切换时,负荷比进程小得多。 电脑基础实例上机系列丛书java程序设计教程清华大学出版社什么是线程此外,由于线程知识在单个进程的作用域内活动,所以线程之间的通信也比进程简单。线程的实现要依赖操作系统,现在一般操作系统都支持线程技术。电脑基础实例上

4、机系列丛书java程序设计教程清华大学出版社什么是线程一个或更多的线程构成了一个进程。一个线程或执行上下文由一个虚拟处理机、cpu执行的代码和代码操作的数据3个主要部分组成。电脑基础实例上机系列丛书java程序设计教程清华大学出版社线程执行的主要组成部分电脑基础实例上机系列丛书java程序设计教程清华大学出版社什么是线程代码可以由多个线程共享,也可以不被共享,这些都和数据是独立的。两个线程如果执行同一个类的实例代码,则它们可以共享相同的代码。电脑基础实例上机系列丛书java程序设计教程清华大学出版社什么是线程类似地,数据可以由多个线程共享,也可以不被共享,这些都和代码是独立的。两个线程如果共享

5、对一个公共对象的存取,则它们可以共享相同的数据。电脑基础实例上机系列丛书java程序设计教程清华大学出版社什么是线程在java编程中,虚拟处理机封装在thread类的一个实例。构造线程时,代码和数据是由传递给它的构造方法的对象指定的。电脑基础实例上机系列丛书java程序设计教程清华大学出版社线程的生命周期 每个java程序都有一个默认的主线程,对于java applicatin应用程序,主线程就是main方法执行的指令序列,对于java applet,主线程指挥浏览器装载并执行java applet。线程在它完整的生命周期中包括新建、就绪、运行、阻塞和死亡5种状态。电脑基础实例上机系列丛书ja

6、va程序设计教程清华大学出版社线程的生命周期新建(new):代表线程的对象已经被初始化,但尚未运行run方法。就绪(runnable):线程正在运行run方法,但这只说明线程目前处于的状态。如果系统没有能力抽出cpu执行时间给线程,线程就“不执行”,这里的“不执行”不代表“阻塞”或“死亡”。电脑基础实例上机系列丛书java程序设计教程清华大学出版社线程的生命周期运行(running):线程获得了cpu资源正在执行任务,将一直运行到结束,除非此时它自动放弃资源或有更加高优先级的线程进入。电脑基础实例上机系列丛书java程序设计教程清华大学出版社线程的生命周期阻塞(blcked):线程是可以执行的

7、,但由于某些因素的阻碍处于停滞状态,系统排程器略过了应给线程的cpu执行时间。死亡(dead):线程的正式结束方式,run方法执行完毕并返回。电脑基础实例上机系列丛书java程序设计教程清华大学出版社多线程技术 多线程是这样一种机制,它允许在程序中并发执行多个指令流,每个指令流都称为一个线程,线程彼此间互相独立。电脑基础实例上机系列丛书java程序设计教程清华大学出版社多线程技术 线程和进程一样拥有独立的执行控制,由操作系统负责调度,区别在于线程没有独立的存储空间,而是和所属进程中的其它线程共享一个存储空间,这使得线程间的通信比进程简单。电脑基础实例上机系列丛书java程序设计教程清华大学出版

8、社多线程技术 多个线程的执行是并发的,也就是在逻辑上“同时”,而不管是否是物理上的“同时”。如果系统只有一个cpu,那么真正的“同时”是不可能的,但是由于cpu的速度非常快,用户感觉不到其中的区别,因此也不用关心它,只需要设想各个线程是同时执行即可。电脑基础实例上机系列丛书java程序设计教程清华大学出版社多线程技术 多线程和传统的单线程在程序设计上最大的区别在于,由于各个线程的控制流彼此独立,使得各个线程之间的代码是无序执行的。电脑基础实例上机系列丛书java程序设计教程清华大学出版社多线程技术的实现 在了解了线程的基本概念之后,本节将继续深入,介绍如何创建线程,如何实现多线程,线程同步、死

9、锁和调度等等多线程技术。线程的创建 如何实现多线程 电脑基础实例上机系列丛书java程序设计教程清华大学出版社多线程技术的实现 线程同步 线程死锁 线程调度 应用举例抢硬币 电脑基础实例上机系列丛书java程序设计教程清华大学出版社线程的创建 为了创建一个新的线程,必须指明这个线程所要执行的代码,java是通过类做到这一点的。作为一个面向对象的程序设计语言,java提供了java.lang.thread类来进行多线程编程,这个类提供了大量的方法给开发人员控制自己的各个线程,以后的讨论都将围绕这个类进行。电脑基础实例上机系列丛书java程序设计教程清华大学出版社线程的创建那么如何提供给java开

10、发人员线程执行的代码呢?通过thread类来实现。主要有两种方法。继承thread类,覆盖方法run() 实现runnable接口 电脑基础实例上机系列丛书java程序设计教程清华大学出版社继承thread类,覆盖方法run()thread类最重要的方法是run()方法,它为thread类的start()方法所调用,并提供线程所要执行的代码。为了指定自己新的代码,只需要覆盖它即可,即在创建的thread类的子类中重写run(),加入线程所要执行的代码。 电脑基础实例上机系列丛书java程序设计教程清华大学出版社继承thread类,覆盖方法run()该方法的步骤是:从thread类派生一个类,覆

11、盖thread类中的run 方法,然后创建该子类的对象,再调用start方法启动本线程。【例10-1】 线程的创建(光盘:源文件第10章例10-1.txt)。电脑基础实例上机系列丛书java程序设计教程清华大学出版社类“drawline”运行结果 类“drawline”运行结果 电脑基础实例上机系列丛书java程序设计教程清华大学出版社继承thread类,覆盖方法run()这种方法简单明了,符合大家的习惯。但是,它也有一个很大的缺点,那就是如果类已经从一个类继承,则无法再继承thread类。如果又不想建立一个新的类,应该怎么办呢?这时可以采用另外一种方法来实现:实现runnable接口。电脑基

12、础实例上机系列丛书java程序设计教程清华大学出版社实现runnable接口 runnable接口只有一个方法run(),可以通过声明自己的类实现runnable接口并提供这一方法,并将线程代码写入其中,就完成了这一部分的任务。但是runnable接口并没有任何对线程的支持,还必须创建thread类的实例,这一点通过thread类的构造方法publicthread(runnable target)来实现。电脑基础实例上机系列丛书java程序设计教程清华大学出版社实现runnable接口【例10-2】 通过实现runnable接口来创建一个线程(光盘:源文件第10章例10-2.txt)。 类“t

13、hreaddemo”运行结果 电脑基础实例上机系列丛书java程序设计教程清华大学出版社实现runnable接口 严格地说,创建thread子类的实例也是可行的,但是必须注意的是,该子类必须没有覆盖thread类的run方法,否则该线程执行的将是子类的run方法,而不是用以实现runnable 接口的类run方法,对此可以试验一下。电脑基础实例上机系列丛书java程序设计教程清华大学出版社实现runnable接口 使用runnable接口来实现多线程使得开发人员能够在一个类中包容所有的代码,有利于封装,但是其缺点在于只能使用一套代码。若想创建多个线程并使各个线程执行不同的代码,则仍必须额外创建

14、类,在大多数情况下这也许还不如直接用多个类分别继承thread更为恰当。电脑基础实例上机系列丛书java程序设计教程清华大学出版社如何实现多线程 java语言提供的实现多线程应用程序的方法主要有如下两种。继承thread类的多线程程序设计方法是使应用程序类继承thread类并且在该类的run方法中实现并发性处理过程。电脑基础实例上机系列丛书java程序设计教程清华大学出版社如何实现多线程 多线程对象实现runnable接口并且在该类中定义用于启动线程的run方法。后一种方法的好处在于多线程应用对象可以继承其它对象而不是必须继承thread类,从而能够增加类定义的逻辑性。电脑基础实例上机系列丛书

15、java程序设计教程清华大学出版社如何实现多线程 这两种方法解决了java实现多线程的技术障碍,是多线程技术实现的核心部分。下面通过例子演示如何使用这两种方法来实现多线程技术。【例10-3】 多线程的实现(光盘:源文件第10章例10-3.txt)。电脑基础实例上机系列丛书java程序设计教程清华大学出版社类“consumer”运行结果 类“consumer”运行结果 电脑基础实例上机系列丛书java程序设计教程清华大学出版社如何实现多线程从上面的程序代码可以看出:多线程类consumer继承java语言中的线程类thread,并且在main方法中创建3个consumer对象的实例。当调用对象实

16、例的start方法时,自动调用consumer类中定义的run方法启动对象线程运行。 电脑基础实例上机系列丛书java程序设计教程清华大学出版社如何实现多线程线程运行的结果是每间隔ntime时间打印出对象实例中的字符串成员变量strconsumer的内容。如果采用实现runnable接口来实现多线程应用程序,则代码如下:电脑基础实例上机系列丛书java程序设计教程清华大学出版社如何实现多线程从上述代码可以看出:该类实现了runnable接口并且在该类中定义了run方法。这种多线程应用程序的实现方式与继承thread类的多线程应用程序的重要区别在于启动多线程对象的方法设计方法不同。在上述代码中,

17、通过创建thread对象实例并且将应用对象作为创建thread类实例的参数。电脑基础实例上机系列丛书java程序设计教程清华大学出版社线程同步 java应用程序的多个线程共享同一进程的数据资源,多个用户线程在并发运行过程中可能同时访问具有共享的内容。在java中定义了线程同步的概念,实现对共享资源的一致性维护。 电脑基础实例上机系列丛书java程序设计教程清华大学出版社线程同步下面以移动通信计费系统中线程间同步控制方法,说明java语言中多线程同步方式的实现过程。在没有多线程同步控制策略条件下,客户账户类定义代码如下所示:电脑基础实例上机系列丛书java程序设计教程清华大学出版社线程同步pub

18、lic class registeraccountfloat fbalance;/客户缴费方法public void deposit(float ffees) fbalance += ffees; 电脑基础实例上机系列丛书java程序设计教程清华大学出版社线程同步/通话计费方法public void withdraw(float ffees) fbalance -= ffees; 电脑基础实例上机系列丛书java程序设计教程清华大学出版社线程同步这段代码也许会被认为:完全能够满足计费系统实际的需要。确实,在单线程环境下该程序确实是可靠的。但是,多进程并发运行的情况是怎样的呢?电脑基础实例上机系

19、列丛书java程序设计教程清华大学出版社线程同步假设发生这种情况:客户在客户服务中心进行缴费的同时也正在利用移动电话进行通话,客户通话结束时计费系统启动计费进程,而同时客户服务中心的工作人员也提交缴费进程运行。可以看到,如果发生这种情况,对客户账户的处理是有冲突的。电脑基础实例上机系列丛书java程序设计教程清华大学出版社线程同步如何解决这种问题呢?很简单,在registeraccount类方法的定义中加上用于标识同步方法的关键字synchronized。这样,在同步方法执行过程中该方法涉及的共享资源将被加上共享锁,以确保在方法运行期间只有该方法能够对共享资源进行访问,直到该方法的线程运行结束

20、打开共享锁,其它线程才能够访问这些共享资源。 电脑基础实例上机系列丛书java程序设计教程清华大学出版社线程同步在共享锁没有打开的时候,其它访问共享资源的线程处于阻塞状态。进行线程同步控制后的registeraccount类定义如下面代码所示:电脑基础实例上机系列丛书java程序设计教程清华大学出版社线程同步public class registeraccount float fbalance; public synchronized void deposit(float ffees) fbalance += ffees; public synchronized void withdraw(f

21、loat ffees) fbalance -= ffees; 电脑基础实例上机系列丛书java程序设计教程清华大学出版社线程同步从以上代码可以看出:在对共享资源进行访问的方法访问属性关键字(public)后附加同步定义关键字synchronized,使得同步方法在对共享资源访问的时候,为这些资源附加共享锁来控制方法执行期间的资源独占性,实现了应用系统数据资源的一致性管理和维护。电脑基础实例上机系列丛书java程序设计教程清华大学出版社线程死锁 死锁是这样一种情形:多个线程同时被阻塞,它们中的一个或者全部都在等待某个资源被释放。由于线程被无限期地阻塞,因此程序不可能正常终止。死锁的根源 隐性死锁

22、 电脑基础实例上机系列丛书java程序设计教程清华大学出版社死锁的根源导致死锁的根源在于不适当地运用synchronized关键字来管理线程对特定对象的访问。前面介绍过,synchronized关键字的作用是,确保在某个时刻只有一个线程被允许执行特定的代码块。因此,被允许执行的线程首先必须拥有对变量或对象的访问权。 电脑基础实例上机系列丛书java程序设计教程清华大学出版社死锁的根源当线程访问对象时,线程会给对象加锁,而这个锁导致其它也想访问同一对象的线程被阻塞,直至第一个线程释放它加在对象上的锁。由于这个原因,在使用synchronized关键词时,很容易出现两个线程互相等待对方做出某个动作

23、的情形。电脑基础实例上机系列丛书java程序设计教程清华大学出版社隐性死锁隐性死锁由于不规范的编程方式引起,但不一定每次测试运行时都会出现程序死锁的情形。由于这个原因,一些隐性死锁可能要到应用正式发布之后才会被发现,因此它的危害性比普通死锁更大。下面介绍两种导致隐性死锁的情况:加锁次序和占有并等待。电脑基础实例上机系列丛书java程序设计教程清华大学出版社隐性死锁1)加锁次序当多个并发的线程分别试图同时占有两个锁时,会出现加锁次序冲突的情形。如果一个线程占有了另一个线程必需的锁,就有可能出现死锁。考虑下面的情形,threada和threadb两个线程分别需要同时拥有lock_1、lock_2两

24、个锁,加锁过程可能如下:电脑基础实例上机系列丛书java程序设计教程清华大学出版社隐性死锁threada获得lock_1。threada被抢占,调度程序转到threadb。threadb获得lock_2。threadb被抢占,调度程序转到threada。threada试图获得lock_2,但lock_2被threadb占有,所以threada阻塞。电脑基础实例上机系列丛书java程序设计教程清华大学出版社隐性死锁调度程序转到threadb。threadb试图获得lock_1,但lock_1被threada占有,所以threadb阻塞。threada和threadb死锁。电脑基础实例上机系列丛书

25、java程序设计教程清华大学出版社隐性死锁必须指出的是,在代码丝毫不做变动的情况下,有些时候上述死锁过程不会出现,调度程序可能让其中一个线程同时获得lock_1和lock_2两个锁,即线程获取两个锁的过程没有被中断。在这种情形下,常规的死锁检测很难确定错误所在。电脑基础实例上机系列丛书java程序设计教程清华大学出版社隐性死锁2)占有并等待如果一个线程获得了一个锁之后还要等待来自另一个线程的通知,可能出现另一种隐性死锁。 以上代码中,producer向队列加入一项新的内容后通知consumer,以便它处理新的内容。 电脑基础实例上机系列丛书java程序设计教程清华大学出版社隐性死锁问题在于,c

26、onsumer可能保持加在队列上的锁,阻止producer访问队列,甚至在consumer等待producer的通知时也会继续保持锁。这样,由于producer不能向队列添加新的内容,而consumer却在等待producer加入新内容的通知,结果就导致死锁。电脑基础实例上机系列丛书java程序设计教程清华大学出版社隐性死锁在等待时占有的锁是一种隐性的死锁,这是因为事情可能按照比较理想的情况发展producer线程不需要被consumer占据的锁。尽管如此,除非有绝对可靠的理由肯定producer线程永远不需要该锁,否则这种编程方式仍是不安全的。 电脑基础实例上机系列丛书java程序设计教程清

27、华大学出版社隐性死锁有时“占有并等待”还可能引发一连串的线程等待。要改正这个错误,只需修改consumer类,把wait()移出synchronized()即可。电脑基础实例上机系列丛书java程序设计教程清华大学出版社线程调度 对于多线程程序,每个线程的重要程度不尽相同,如多个线程在等待获得cpu时间时,往往需要优先级高的线程优先抢占到cpu时间得以执行;又如多个线程交替执行时,优先级决定了级别高的线程得到cpu的次数多一些且时间长一些。这样,高优先级的线程处理的任务效率就高一些。电脑基础实例上机系列丛书java程序设计教程清华大学出版社线程调度线程通常是抢占式的而不需要时间片分配进程。抢占

28、式调度模型就是许多线程属于可以运行状态,但实际上只有一个线程在运行。该线程一直运行到它终止进入可运行状态或是另一个具有更高优先级的线程变成可运行状态。 电脑基础实例上机系列丛书java程序设计教程清华大学出版社线程调度后一种情况下,低优先级的线程被高优先级的线程抢占,高优先级的线程获得运行的机会。线程可以因为各种各样的原因进入阻塞状态。电脑基础实例上机系列丛书java程序设计教程清华大学出版社线程调度所有可运行的线程根据优先级保持在不同的池中。一旦被阻塞的线程返回可运行状态,它将会被放回适当的可运行池中。非空最高优先级池中的线程将获得cpu时间。 java中线程的优先级从低到高以整数110表示,共分为10级,设置优先级是通过调用线程对象的setpriority()方法。电脑基础实例上机系列丛书java程序设计教程清华大学出版社线程调度java的object类提供了3个方法来实现线程的调度和通信。wait()等待:当前线程放弃监视器并进入睡眠状态,直到其他线程进入同一监视器并调用notify()为止。电脑基础实例上机系列丛书java程序设计教程清华大学出版社线程调度notify()唤醒:唤醒同一

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论