第9章 Java多线程.ppt

上传人:hwp****526 文档编号:84396447 上传时间:2023-04-05 格式:PPT 页数:42 大小:373KB
返回 下载 相关 举报
第9章 Java多线程.ppt_第1页
第1页 / 共42页
第9章 Java多线程.ppt_第2页
第2页 / 共42页
点击查看更多>>
资源描述

《第9章 Java多线程.ppt》由会员分享,可在线阅读,更多相关《第9章 Java多线程.ppt(42页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。

1、第第9章章 Java多线程多线程学习导读学习导读n多线程机制使得程序的多个子任务能够“同时”执行n多线程是指同时存在几个执行体,按几条不同的执行线索共同工作的情况。Java语言实现了对多线程的支持,它使得编程人员可以很方便地开发出能同时处理多个任务的功能强大的应用程序。n在Java语言中,不仅语言本身有多线程的支持,可以方便地生成多线程的程序,而且运行环境也利用多线程的应用程序并发提供多种服务。n本章介绍如何实现Java语言中的多线程机制2课程结构课程结构n9.1 多线程基本概念多线程基本概念n9.2 创建线程的方式创建线程的方式n9.3 线程的挂起与唤醒线程的挂起与唤醒n9.4 多线程问题多

2、线程问题3 9.1 多线程基本概念多线程基本概念文件文件输入输出装置输入输出装置各种系统资源各种系统资源数据区段数据区段程序区段程序区段只有一个地方在执行只有一个地方在执行文件文件输入输出装置输入输出装置各种系统资源各种系统资源数据区段数据区段程序区段程序区段同时有数个地方在执行同时有数个地方在执行传统的进程传统的进程多线程的任务多线程的任务49.1 多线程基本概念多线程基本概念n多线程的优势多线程的优势:n减轻编写交互频繁、涉及面多的程序的困难减轻编写交互频繁、涉及面多的程序的困难.n程序的吞吐量会得到改善程序的吞吐量会得到改善.n由多个处理器的系统由多个处理器的系统,可以并发运行不同的线可

3、以并发运行不同的线程程.(否则否则,任何时刻只有一个线程在运行任何时刻只有一个线程在运行)59.1 多线程基本概念多线程基本概念n一、线程与进程的区别一、线程与进程的区别:n多个进程的内部数据和状态都是完全独立的多个进程的内部数据和状态都是完全独立的,而多线程是共享一块内存空间和一组系统资而多线程是共享一块内存空间和一组系统资源源,有可能互相影响有可能互相影响.n线程本身的数据通常只有寄存器数据,以及线程本身的数据通常只有寄存器数据,以及一个程序执行时使用的堆栈,所以线程的切一个程序执行时使用的堆栈,所以线程的切换比进程切换的负担要小。换比进程切换的负担要小。69.1 多线程基本概念多线程基本

4、概念n二、线程的状态和生命周期二、线程的状态和生命周期n1新建新建n2就绪就绪n3运行运行n4阻塞阻塞n5死亡死亡79.1 多线程基本概念多线程基本概念n1新建新建n当当一一个个Thread类类或或其其子子类类的的对对象象被被声声明明并并创创建建时时,新新生生的的线线程程对对象象处处于于新新建建状状态态。此此时时它它已已经经有有了了相相应的内存空间和其他资源,并已被初始化。应的内存空间和其他资源,并已被初始化。n2就绪就绪n处处于于新新建建状状态态的的线线程程被被启启动动后后,将将进进入入线线程程队队列列排排队队等等待待CPU时时间间片片,此此时时它它已已经经具具备备了了运运行行的的条条件件,

5、一一旦旦轮轮到到它它来来享享用用CPU资资源源时时,就就可可以以脱脱离离创创建建它它的的主主线线程程独独立立开开始始自自己己的的生生命命周周期期了了。另另外外,原原来来处处于于阻阻塞塞状状态态的的线线程程被被解解除除阻阻塞塞后后也也将将进进入入就就绪绪状状态。态。89.1 多线程基本概念多线程基本概念n3运行运行n当就绪状态的线程被调度并获得处理器资源当就绪状态的线程被调度并获得处理器资源时,便进入运行状态。时,便进入运行状态。nrunrun方法方法n每一个每一个Thread类及其子类的对象都有一个重类及其子类的对象都有一个重要的要的run()方法,当线程对象被调度执行时,方法,当线程对象被调

6、度执行时,它将自动调用本对象的它将自动调用本对象的run()方法,从第一句方法,从第一句开始顺序执行。开始顺序执行。run()方法定义了这一类线程方法定义了这一类线程的操作和功能。的操作和功能。99.1 多线程基本概念多线程基本概念n4阻塞阻塞n一个正在执行的线程如果在某些特殊情况下,一个正在执行的线程如果在某些特殊情况下,如被人为挂起或需要执行费时的输入输出操作如被人为挂起或需要执行费时的输入输出操作时,将让出时,将让出CPU并暂时中止自己的执行,进入并暂时中止自己的执行,进入阻塞状态。阻塞状态。n阻塞时它不能进入排列队列,只有当引起阻阻塞时它不能进入排列队列,只有当引起阻塞的原因被消除时,

7、线程才可以转入就绪状态,塞的原因被消除时,线程才可以转入就绪状态,重新进到线程队列中排队等待重新进到线程队列中排队等待CPU资源,以便资源,以便从原来终止处开始继续执行。从原来终止处开始继续执行。109.1 多线程基本概念多线程基本概念n5死亡死亡n处于死亡状态的线程不具有继续运行的能力。处于死亡状态的线程不具有继续运行的能力。线程死亡的原因有两个:线程死亡的原因有两个:n一个是正常运行的线程完成了它的全部工作,一个是正常运行的线程完成了它的全部工作,即执行完了即执行完了run()方法的最后一个语句并退出;方法的最后一个语句并退出;n另一个是线程被提前强制性地终止,如通过另一个是线程被提前强制

8、性地终止,如通过执行执行stop()方法或方法或destroy()终止线程。终止线程。119.1 多线程基本概念多线程基本概念n三、线程调度与优先级三、线程调度与优先级n处于就绪状态的线程排队等候处理器资源处于就绪状态的线程排队等候处理器资源n线程先分配线程先分配CPU资源的先后,称为线程调度资源的先后,称为线程调度n为了方便线程调度,多线程系统会给每个线为了方便线程调度,多线程系统会给每个线程自动分配一个线程的优先级,任务较紧急程自动分配一个线程的优先级,任务较紧急重要的线程,其优先级就较高;相反则较低重要的线程,其优先级就较高;相反则较低 n在在Java系统中,线程调度采用优先级基础上系统

9、中,线程调度采用优先级基础上的的“先到先服务先到先服务”原则原则 129.1 多线程基本概念多线程基本概念n四、线程组四、线程组 n在在Java中,线程组是类中,线程组是类ThreadGroup的对象,的对象,每个线程每个线程Thread都隶属于惟一一个线程组都隶属于惟一一个线程组n这个线程组在线程创建时指定并在线程的整这个线程组在线程创建时指定并在线程的整个生命期内都不能更改个生命期内都不能更改n用户可以通过调用包含用户可以通过调用包含 ThreadGroup 类型类型参数的参数的 Thread 类构造函数来指定线程所属类构造函数来指定线程所属的线程组。的线程组。139.1 多线程基本概念多

10、线程基本概念n在创建线程时显式地制定线程组,采用下述在创建线程时显式地制定线程组,采用下述三种构造方法之一:三种构造方法之一:1)Thread(ThreadGroup,Runnable)2)Thread(ThreadGroup,String)3)Thread(ThreadGroup,Runnable,String)n若没有指定,则线程默认地隶属于名为若没有指定,则线程默认地隶属于名为system的系统线程组的系统线程组 n例如,下面的语句创建了一个名为例如,下面的语句创建了一个名为myThreadGroup的线程组:的线程组:ThreadGroup myThreadGroup=new Thre

11、adGroup(“my Group of Threads”)149.1 多线程基本概念多线程基本概念n线程组的作用:线程组的作用:nJava允许对一个线程组中的所有线程同时进允许对一个线程组中的所有线程同时进行操作,比如可以通过调用线程组的相应方行操作,比如可以通过调用线程组的相应方法来设置其中所有线程的优先级,也可以启法来设置其中所有线程的优先级,也可以启动或阻塞其中的所有线程动或阻塞其中的所有线程 nJava的线程组机制的另一个重要作用是线程的线程组机制的另一个重要作用是线程安全。线程组机制允许通过分组来区分有不安全。线程组机制允许通过分组来区分有不同安全特性的线程,对不同组的线程进行不同

12、安全特性的线程,对不同组的线程进行不同的处理,还可以通过线程组的分层结构来同的处理,还可以通过线程组的分层结构来支持不对等安全措施的采用支持不对等安全措施的采用 159.1 多线程基本概念多线程基本概念n五、守护线程五、守护线程 169.1 多线程基本概念多线程基本概念n对线程的综合支持是对线程的综合支持是Java技术的一个重要特技术的一个重要特色色.它提供了它提供了thread类、监视器和条件变量的类、监视器和条件变量的技术技术.n虽然虽然Macintosh,Windows NT,Windows 9等操等操作系统支持多线程作系统支持多线程,但若要用但若要用C或或C+编写多编写多线程程序是十分

13、困难的,因为它们对数据同线程程序是十分困难的,因为它们对数据同步的支持不充分步的支持不充分.179.2 创建线程的方式创建线程的方式nJava中编程实现多线程应用有两种途径:中编程实现多线程应用有两种途径:创建用户自己的线程子类,创建用户自己的线程子类,在用户自己的类中实现在用户自己的类中实现Runnable接口接口189.2 创建线程的方式创建线程的方式nThread类类n1、构造函数、构造函数publicThread();这这个个方方法法创创建建了了一一个个默默认认的的线线程类的对象。程类的对象。PublicThread(Runnabletarget);这这个个方方法法在在上上一一 个个

14、构构 造造 函函 数数 的的 基基 础础 上上,利利 用用 一一 个个 实实 现现 了了Runnable接接口口参参数数对对象象Target中中所所定定义义的的run()方方法法,以以便便初初始始化化或或覆覆盖盖新新创创建建的的线线程程对对象象的的run()()方法。方法。publicThread(Stringname);利利用用一一个个String类类的的对对象象name为为所所创创建建的的线线程程对对象象指指定定了了一一个个名名称称4199.2 创建线程的方式创建线程的方式nThread类类n1、构造函数、构造函数PublicThread(ThreadGroupgroup,Runnable

15、target)这这个个方方法法利利用用给给出出的的ThreadGroup类类的的对对象象为为所所创创建建的的线线程程指定了所属的线程组。指定了所属的线程组。publicThread(ThreadGroupgroup,Stringname);这这个个方方法法在在第第三三个个构构造造函函数数创创建建了了一一个个指指定定了了一一个个字字符符串串名名称称的的线线程程对对象象的的基基础础上上,利利用用给给出出的的ThreadGroup类类的的对对象为所创建的线程指定了所属的线程组。象为所创建的线程指定了所属的线程组。public Thread(ThreadGroupgroup,Runnabletarge

16、t,Stringname);这这个个方方法法综综合合了了上上面面提提到到的的几几种种情情况况,创创建建了了一一个个属属于于group的的线线程程组组,用用target对对象象中中的的run()方方法法初初始始化化了了本本线线程程中中的的run()方方法法,同同时时还还为为线线程程指指定定了了一一个字符串名。个字符串名。209.2 创建线程的方式创建线程的方式nThread类类n2、优先级、优先级nThread类有三个有关线程优先级的静态常量:类有三个有关线程优先级的静态常量:publicstaticfinalintMAX_PRIORITYpublicstaticfinalintMIN_PRIO

17、RITYpublic static final int NORM_PRIORITY 219.2 创建线程的方式创建线程的方式nThread类类n2、优先级、优先级n对对应应一一个个新新建建线线程程,系系统统会会根根据据如如下下的的原原则则为为其自定义的优先级:其自定义的优先级:新建线程将继承创建它的父线程的优先级。新建线程将继承创建它的父线程的优先级。一般情况下,主线程具有普通优先级。一般情况下,主线程具有普通优先级。另另外外,用用户户可可以以通通过过调调用用Thread类类的的方方法法setPriority()来来修修改改系系统统自自动动设设定定的的线线程程优优先先级级,使使之之符符合合程程

18、序的特定需要序的特定需要229.2 创建线程的方式创建线程的方式nRunnable接口接口nRunnable接口只有一个方法接口只有一个方法run(),(),所有实所有实现现Runnable接口的用户类都必须具体实现这个接口的用户类都必须具体实现这个run()()方法方法n当线程被调度并转入运行状态时,它所执行的当线程被调度并转入运行状态时,它所执行的就是就是run()()方法中规定的操作。方法中规定的操作。n一个实现一个实现Runnable接口的类实际上定义了一个接口的类实际上定义了一个主线程之外新线程的操作,主线程之外新线程的操作,239.2 创建线程的方式创建线程的方式1.继承类继承类T

19、hread public class mythread extends Thread2.public class mythread extends Applet implements Runnable (小应用或已经是某个类的子类小应用或已经是某个类的子类时时)3.上述两种方法中都可用上述两种方法中都可用类类Thread产生线程的产生线程的对象对象 Thread newthread;4.创建并启动线程创建并启动线程 newthread=new Thread(this);newthread.start();249.2 创建线程的方式创建线程的方式n5.run方法是运行线程的主体方法是运行线程的主

20、体,启动线程时启动线程时,由由java直接调用直接调用 public void run()n6.停止线程停止线程,调用线程的调用线程的stop()()newthread.stop()n7 sleep方法的作用方法的作用,暂停线程的执行暂停线程的执行,让其它线让其它线程得到机会程得到机会,sleep要丢出异常要丢出异常,必须抓住必须抓住.nTrysleep(100)catch(InterruptedException e)n 259.2 创建线程的方式创建线程的方式8.其它常用的方法其它常用的方法 isAlive:判断线程目前是否正在执行状态中判断线程目前是否正在执行状态中 if(newthre

21、ad.isAlive()newthread.stop();resume:要求被暂停得线程继续执行要求被暂停得线程继续执行 suspend:暂停线程的执行暂停线程的执行 join:等待线程执行完毕等待线程执行完毕 thatThread.join();被等待的那个线程不结束被等待的那个线程不结束,当当前线程就一直等待前线程就一直等待.yield:将执行的权力交给其它线程将执行的权力交给其它线程,自己到队列自己到队列的最后等待的最后等待.269.2 创建线程的方式创建线程的方式new Thread()New ThreadRunnablestart()Not Runnablestop()stop()D

22、eadyield()stop()orrun()exit.suspend()sleep()wait()resume().11.线程的状态线程的状态279.2 创建线程的方式创建线程的方式n多线程并发程序多线程并发程序n如如前前所所述述,在在程程序序中中实实现现多多线线程程并并发发程程序序有有两两个途径:个途径:一是创建一是创建Thread类的子类;类的子类;另一个是实现另一个是实现Runnable接口。接口。n程序员应该控制的关键性操作有两个:程序员应该控制的关键性操作有两个:定定义义用用户户线线程程的的操操作作,即即定定义义用用户户线线程程中中的的run()方法。方法。在在适适当当的的时时候候

23、建建立立用用户户线线程程并并用用start()方方法法启启动动线线程程,如如果果需需要要,还还要要在在适适当当的的时时候候休休眠眠或或挂挂起起线线程。程。289.2 创建线程的方式创建线程的方式n 多线程并发程序多线程并发程序n1、使用、使用Thread类的子类类的子类n见书见书P181例例9.1 9.2 9.3n2、利用实现利用实现Runnable接口实现接口实现n见书见书P185例例9.4 9.5299.3 线程的挂起与唤醒线程的挂起与唤醒n暂停线程的执行等待条件满足再执行暂停线程的执行等待条件满足再执行.n下面的例子显示线程的挂起和唤醒下面的例子显示线程的挂起和唤醒n小应用程序第一次开始

24、时小应用程序第一次开始时,线程被启动线程被启动n浏览器改变页面时浏览器改变页面时,小应用程序小应用程序的的stop()方法方法被调用被调用,线程被挂起线程被挂起.n浏览器回到原来的页面时浏览器回到原来的页面时,线程被唤醒线程被唤醒.309.3 线程的挂起与唤醒线程的挂起与唤醒public void start()if(mythread=null)mythread=new Thread();mythread.start();else mythread.resume();public void run()while(true)trysleep(100);catch(InterruptedExcep

25、tion e)public void stop()mythread.suspend();.319.4 多多线程问题线程同步线程问题线程同步n一、什么是线程同步问题一、什么是线程同步问题n在在多多线线程程的的程程序序中中,当当多多个个线线程程并并发发执执行行时时,由由于线程的相对执行顺序是不确定的。于线程的相对执行顺序是不确定的。n当当多多个个并并发发线线程程需需要要共共享享程程序序的的代代码码区区域域和和数数据据区区域域时时,由由于于各各线线程程的的执执行行顺顺序序是是不不确确定定的的,因因此此执执行行的的结结果果就就带带有有不不确确定定性性,这这就就要要求求线线程程同同步步329.4 多多线

26、程问题线程同步线程问题线程同步n一、什么是线程同步问题一、什么是线程同步问题n见书见书P190P190例例9.69.6 n错错误误的的原原因因是是:在在实实际际的的存存款款业业务务中中,对对同同一一账账户户的的两两笔笔存存款款是是互互斥斥的的,即即只只有有当当一一笔笔存存款款结结束束以以后后,才才能能在在其其基基础础上上进进行行另另一一笔笔存存款款;而而上上面面的的程程序序中中两两笔笔存存款款是是交交替替进进行行的的,它它们们所所取取得得的的存存款款余余额额都都是是最最初初的的3000,并并分分别别对对该该余余额额进进行行操操作作,所所以以得得到到了了结结果果是是4500元元的的情情况况,显显

27、然然是是错误的错误的 339.4 多多线程问题线程同步线程问题线程同步n二、临界区和线程同步二、临界区和线程同步n在多线程程序设计中,我们将程序中那些不能被在多线程程序设计中,我们将程序中那些不能被多个线程并发执行的代码段称为临界区多个线程并发执行的代码段称为临界区n当某个线程已处于临界区时,其他的线程就不允当某个线程已处于临界区时,其他的线程就不允许再进入临界区许再进入临界区 n实实 现现 方方 法法:则则 是是 在在 共共 享享 代代 码码 之之 前前 加加 入入synchronized段段,把把 共共 享享 代代 码码 包包 含含 在在synchronized段中,格式如下:段中,格式如

28、下:synchronized(objectname)statement其其中中,objectname用用于于指指出出该该临临界界区区的的监监控控对对象象,是可选项;是可选项;statement为为临临界界区区,它它既既可可以以是是一一个个方方法法,称称为为同同步方法,也可以是一段程序代码,称为同步语句块步方法,也可以是一段程序代码,称为同步语句块349.4 多多线程问题线程同步线程问题线程同步n二、临界区和线程同步二、临界区和线程同步n下列语句定义了一个同步方法下列语句定义了一个同步方法method1()synchronizedintmethod1()n下列语句定义了一个同步语句块下列语句定义

29、了一个同步语句块intmethod1()synchronized(this)359.4 多多线程问题线程同步线程问题线程同步n三、三、PV操作(操作(wait方法和方法和notify方法)方法)n1wait()方法nwait()方法用于使当前线程放弃临界区而处于睡方法用于使当前线程放弃临界区而处于睡眠状态,直到有另一线程调用眠状态,直到有另一线程调用notify()方法将它方法将它唤醒或睡眠时间已到为止,其格式如下:唤醒或睡眠时间已到为止,其格式如下:wait();wait(millis);其中其中millis是睡眠时间是睡眠时间 369.4 多多线程问题线程同步线程问题线程同步n 2noti

30、fy()方法nnotify()方法用于将处于睡眠状态的某个等待当方法用于将处于睡眠状态的某个等待当前对象监控器的线程唤醒。前对象监控器的线程唤醒。n如果有多个这样的线程,则按照先进先出的原则如果有多个这样的线程,则按照先进先出的原则唤醒第一个线程。唤醒第一个线程。nObject类中还提供了另一个方法类中还提供了另一个方法notifyAll(),用用于唤醒所有因调用于唤醒所有因调用wait()方法而睡眠的线程。方法而睡眠的线程。379.4 多多线程问题线程同步线程问题线程同步n四、生产者四、生产者消费者问题消费者问题 n在在“生产者生产者消费者消费者”问题中,问题中,“生产者生产者”不断不断生产

31、产品并将其放在产品队列中,而生产产品并将其放在产品队列中,而“消费者消费者”则不断从产品队列中取出产品则不断从产品队列中取出产品 n这里用两个线程模拟这里用两个线程模拟“生产者生产者”和和“消费者消费者”,用一个数据对象模拟产品用一个数据对象模拟产品 n没有考虑线程同步的程序:书上没有考虑线程同步的程序:书上P195例例9.7 n本例中由于没有考虑生产者本例中由于没有考虑生产者消费者的的对临界消费者的的对临界区的访问的冲突,回得到完全错误的结果区的访问的冲突,回得到完全错误的结果389.4 多多线程问题线程同步线程问题线程同步n为了解决这一问题,引入了等待通知为了解决这一问题,引入了等待通知(

32、wait/notify)机制:机制:n1)在生产者没有生产之前,通知消费者等)在生产者没有生产之前,通知消费者等待;在生产者生产之后,马上通知消费者消费。待;在生产者生产之后,马上通知消费者消费。n2)在消费者消费了之后,通知生产者已经)在消费者消费了之后,通知生产者已经消费完,需要生产。消费完,需要生产。n见书上见书上P195例例9.8399.4 多多线程问题线程同步线程问题线程同步n五、死锁五、死锁n死锁是指两个或多个线程无休止地互相等待对方死锁是指两个或多个线程无休止地互相等待对方释放所占据资源的过程。错误的同步往往会引起释放所占据资源的过程。错误的同步往往会引起死锁。为了防止死锁,在进

33、行多线程程序设计时死锁。为了防止死锁,在进行多线程程序设计时必须遵循如下原则:必须遵循如下原则:n1)在指定的任务真正需要并发时,才采用多线)在指定的任务真正需要并发时,才采用多线程来进行程序设计。程来进行程序设计。n2)在对象的同步方法中需要调用其他同步方法)在对象的同步方法中需要调用其他同步方法时必须小心。时必须小心。n3)在临界区中的时间应尽可能短,需要长时间)在临界区中的时间应尽可能短,需要长时间运行的任务尽量不要放在临界区中。运行的任务尽量不要放在临界区中。40本章小结本章小结1.实现线程有两种方法实现线程有两种方法:n实现实现Ruannable接口接口n继承继承Thread类类2.在小应用中通常在在小应用中通常在start中创建线程中创建线程3.当新线程被启动时当新线程被启动时,java调用该线程的调用该线程的run方方 法法,它是它是Thread的核心的核心.4.线程由五个状态线程由五个状态:新建,就绪,运行,阻塞,新建,就绪,运行,阻塞,死亡死亡41本章小结本章小结5.两个或多个线程竞争资源时两个或多个线程竞争资源时,需要用同步的方需要用同步的方法协调资源法协调资源.6.多个线程执行时多个线程执行时,要用到同步方法要用到同步方法,即使用即使用 synchronized的关键字设定同步区的关键字设定同步区7.wait和和notify起协调作用起协调作用42

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

当前位置:首页 > 生活休闲 > 生活常识

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知淘文阁网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号© 2020-2023 www.taowenge.com 淘文阁