第9章 Java多线程ppt课件.ppt

第9章 Java多线程ppt课件.ppt

ID:58697122

大小:355.00 KB

页数:42页

时间:2020-10-04

上传者:U-5649
第9章 Java多线程ppt课件.ppt_第1页
第9章 Java多线程ppt课件.ppt_第2页
第9章 Java多线程ppt课件.ppt_第3页
第9章 Java多线程ppt课件.ppt_第4页
第9章 Java多线程ppt课件.ppt_第5页
资源描述:

《第9章 Java多线程ppt课件.ppt》由会员上传分享,免费在线阅读,更多相关内容在教育资源-天天文库

第9章Java多线程 学习导读多线程机制使得程序的多个子任务能够“同时”执行多线程是指同时存在几个执行体,按几条不同的执行线索共同工作的情况。Java语言实现了对多线程的支持,它使得编程人员可以很方便地开发出能同时处理多个任务的功能强大的应用程序。在Java语言中,不仅语言本身有多线程的支持,可以方便地生成多线程的程序,而且运行环境也利用多线程的应用程序并发提供多种服务。本章介绍如何实现Java语言中的多线程机制2 课程结构9.1多线程基本概念9.2创建线程的方式9.3线程的挂起与唤醒9.4多线程问题3 9.1多线程基本概念文件输入输出装置各种系统资源数据区段程序区段只有一个地方在执行文件输入输出装置各种系统资源数据区段程序区段同时有数个地方在执行传统的进程多线程的任务4 9.1多线程基本概念多线程的优势:减轻编写交互频繁、涉及面多的程序的困难.程序的吞吐量会得到改善.由多个处理器的系统,可以并发运行不同的线程.(否则,任何时刻只有一个线程在运行)5 9.1多线程基本概念一、线程与进程的区别:多个进程的内部数据和状态都是完全独立的,而多线程是共享一块内存空间和一组系统资源,有可能互相影响.线程本身的数据通常只有寄存器数据,以及一个程序执行时使用的堆栈,所以线程的切换比进程切换的负担要小。6 9.1多线程基本概念二、线程的状态和生命周期1.新建2.就绪3.运行4.阻塞5.死亡7 9.1多线程基本概念1.新建当一个Thread类或其子类的对象被声明并创建时,新生的线程对象处于新建状态。此时它已经有了相应的内存空间和其他资源,并已被初始化。2.就绪处于新建状态的线程被启动后,将进入线程队列排队等待CPU时间片,此时它已经具备了运行的条件,一旦轮到它来享用CPU资源时,就可以脱离创建它的主线程独立开始自己的生命周期了。另外,原来处于阻塞状态的线程被解除阻塞后也将进入就绪状态。8 9.1多线程基本概念3.运行当就绪状态的线程被调度并获得处理器资源时,便进入运行状态。run方法每一个Thread类及其子类的对象都有一个重要的run()方法,当线程对象被调度执行时,它将自动调用本对象的run()方法,从第一句开始顺序执行。run()方法定义了这一类线程的操作和功能。9 9.1多线程基本概念4.阻塞一个正在执行的线程如果在某些特殊情况下,如被人为挂起或需要执行费时的输入输出操作时,将让出CPU并暂时中止自己的执行,进入阻塞状态。阻塞时它不能进入排列队列,只有当引起阻塞的原因被消除时,线程才可以转入就绪状态,重新进到线程队列中排队等待CPU资源,以便从原来终止处开始继续执行。10 9.1多线程基本概念5.死亡处于死亡状态的线程不具有继续运行的能力。线程死亡的原因有两个:一个是正常运行的线程完成了它的全部工作,即执行完了run()方法的最后一个语句并退出;另一个是线程被提前强制性地终止,如通过执行stop()方法或destroy()终止线程。11 9.1多线程基本概念三、线程调度与优先级处于就绪状态的线程排队等候处理器资源线程先分配CPU资源的先后,称为线程调度为了方便线程调度,多线程系统会给每个线程自动分配一个线程的优先级,任务较紧急重要的线程,其优先级就较高;相反则较低在Java系统中,线程调度采用优先级基础上的“先到先服务”原则12 9.1多线程基本概念四、线程组在Java中,线程组是类ThreadGroup的对象,每个线程Thread都隶属于惟一一个线程组这个线程组在线程创建时指定并在线程的整个生命期内都不能更改用户可以通过调用包含ThreadGroup类型参数的Thread类构造函数来指定线程所属的线程组。13 9.1多线程基本概念在创建线程时显式地制定线程组,采用下述三种构造方法之一:1)Thread(ThreadGroup,Runnable)2)Thread(ThreadGroup,String)3)Thread(ThreadGroup,Runnable,String)若没有指定,则线程默认地隶属于名为system的系统线程组例如,下面的语句创建了一个名为myThreadGroup的线程组:ThreadGroupmyThreadGroup=newThreadGroup(“myGroupofThreads”)14 9.1多线程基本概念线程组的作用:Java允许对一个线程组中的所有线程同时进行操作,比如可以通过调用线程组的相应方法来设置其中所有线程的优先级,也可以启动或阻塞其中的所有线程Java的线程组机制的另一个重要作用是线程安全。线程组机制允许通过分组来区分有不同安全特性的线程,对不同组的线程进行不同的处理,还可以通过线程组的分层结构来支持不对等安全措施的采用15 9.1多线程基本概念五、守护线程16 9.1多线程基本概念对线程的综合支持是Java技术的一个重要特色.它提供了thread类、监视器和条件变量的技术.虽然Macintosh,WindowsNT,Windows9等操作系统支持多线程,但若要用C或C++编写多线程程序是十分困难的,因为它们对数据同步的支持不充分.17 9.2创建线程的方式Java中编程实现多线程应用有两种途径:创建用户自己的线程子类,在用户自己的类中实现Runnable接口18 9.2创建线程的方式Thread类1、构造函数publicThread();这个方法创建了一个默认的线程类的对象。PublicThread(Runnable target);这个方法在上一个构造函数的基础上,利用一个实现了Runnable接口参数对象Target中所定义的run()方法,以便初始化或覆盖新创建的线程对象的run()方法。publicThread(String name);利用一个String类的对象name为所创建的线程对象指定了一个名称419 9.2创建线程的方式Thread类1、构造函数PublicThread(ThreadGroup group,Runnabletarget)这个方法利用给出的ThreadGroup类的对象为所创建的线程指定了所属的线程组。publicThread(ThreadGroupgroup,Stringname);这个方法在第三个构造函数创建了一个指定了一个字符串名称的线程对象的基础上,利用给出的ThreadGroup类的对象为所创建的线程指定了所属的线程组。publicThread(ThreadGroupgroup,Runnabletarget,Stringname);这个方法综合了上面提到的几种情况,创建了一个属于group的线程组,用target对象中的run()方法初始化了本线程中的run()方法,同时还为线程指定了一个字符串名。20 9.2创建线程的方式Thread类2、优先级Thread类有三个有关线程优先级的静态常量:publicstaticfinalintMAX_PRIORITYpublicstaticfinalintMIN_PRIORITYpublicstaticfinalintNORM_PRIORITY21 9.2创建线程的方式Thread类2、优先级对应一个新建线程,系统会根据如下的原则为其自定义的优先级:新建线程将继承创建它的父线程的优先级。一般情况下,主线程具有普通优先级。另外,用户可以通过调用Thread类的方法setPriority()来修改系统自动设定的线程优先级,使之符合程序的特定需要22 9.2创建线程的方式Runnable接口Runnable接口只有一个方法run(),所有实现Runnable接口的用户类都必须具体实现这个run()方法当线程被调度并转入运行状态时,它所执行的就是run()方法中规定的操作。一个实现Runnable接口的类实际上定义了一个主线程之外新线程的操作,23 9.2创建线程的方式1.继承类ThreadpublicclassmythreadextendsThread2.publicclassmythreadextendsAppletimplementsRunnable(小应用或已经是某个类的子类时)3.上述两种方法中都可用类Thread产生线程的对象Threadnewthread;4.创建并启动线程newthread=newThread(this);newthread.start();24 9.2创建线程的方式5.run方法是运行线程的主体,启动线程时,由java直接调用publicvoidrun()6.停止线程,调用线程的stop()newthread.stop()7sleep方法的作用,暂停线程的执行,让其它线程得到机会,sleep要丢出异常,必须抓住.Try{sleep(100)}catch(InterruptedExceptione){}25 9.2创建线程的方式8.其它常用的方法isAlive:判断线程目前是否正在执行状态中if(newthread.isAlive())newthread.stop();resume:要求被暂停得线程继续执行suspend:暂停线程的执行join:等待线程执行完毕thatThread.join();被等待的那个线程不结束,当前线程就一直等待.yield:将执行的权力交给其它线程,自己到队列的最后等待.26 9.2创建线程的方式newThread()NewThreadRunnablestart()NotRunnablestop()stop()Deadyield()stop()orrun()exit..suspend()sleep()wait()resume().11.线程的状态27 9.2创建线程的方式多线程并发程序如前所述,在程序中实现多线程并发程序有两个途径:一是创建Thread类的子类;另一个是实现Runnable接口。程序员应该控制的关键性操作有两个:定义用户线程的操作,即定义用户线程中的run()方法。在适当的时候建立用户线程并用start()方法启动线程,如果需要,还要在适当的时候休眠或挂起线程。28 9.2创建线程的方式多线程并发程序1、使用Thread类的子类见书P181例9.19.29.32、利用实现Runnable接口实现见书P185例9.49.529 9.3线程的挂起与唤醒暂停线程的执行等待条件满足再执行.下面的例子显示线程的挂起和唤醒小应用程序第一次开始时,线程被启动浏览器改变页面时,小应用程序的stop()方法被调用,线程被挂起.浏览器回到原来的页面时,线程被唤醒.30 9.3线程的挂起与唤醒publicvoidstart(){if(mythread==null){mythread=newThread();mythread.start();}else{mythread.resume();}}publicvoidrun(){while(true){try{sleep(100);}catch(InterruptedExceptione){}}}publicvoidstop(){mythread.suspend();}.31 9.4多线程问题-线程同步一、什么是线程同步问题在多线程的程序中,当多个线程并发执行时,由于线程的相对执行顺序是不确定的。当多个并发线程需要共享程序的代码区域和数据区域时,由于各线程的执行顺序是不确定的,因此执行的结果就带有不确定性,这就要求线程同步32 9.4多线程问题-线程同步一、什么是线程同步问题见书P190例9.6错误的原因是:在实际的存款业务中,对同一账户的两笔存款是互斥的,即只有当一笔存款结束以后,才能在其基础上进行另一笔存款;而上面的程序中两笔存款是交替进行的,它们所取得的存款余额都是最初的3000,并分别对该余额进行操作,所以得到了结果是4500元的情况,显然是错误的33 9.4多线程问题-线程同步二、临界区和线程同步在多线程程序设计中,我们将程序中那些不能被多个线程并发执行的代码段称为临界区当某个线程已处于临界区时,其他的线程就不允许再进入临界区实现方法:则是在共享代码之前加入synchronized段,把共享代码包含在synchronized段中,格式如下:synchronized[(objectname)]statement其中,objectname用于指出该临界区的监控对象,是可选项;statement为临界区,它既可以是一个方法,称为同步方法,也可以是一段程序代码,称为同步语句块34 9.4多线程问题-线程同步二、临界区和线程同步下列语句定义了一个同步方法method1()synchronizedintmethod1(){……}下列语句定义了一个同步语句块intmethod1(){synchronized(this){……}}35 9.4多线程问题-线程同步三、PV操作(wait方法和notify方法)1.wait()方法wait()方法用于使当前线程放弃临界区而处于睡眠状态,直到有另一线程调用notify()方法将它唤醒或睡眠时间已到为止,其格式如下:wait();wait(millis);其中millis是睡眠时间36 9.4多线程问题-线程同步2.notify()方法notify()方法用于将处于睡眠状态的某个等待当前对象监控器的线程唤醒。如果有多个这样的线程,则按照先进先出的原则唤醒第一个线程。Object类中还提供了另一个方法notifyAll(),用于唤醒所有因调用wait()方法而睡眠的线程。37 9.4多线程问题-线程同步四、生产者—消费者问题在“生产者—消费者”问题中,“生产者”不断生产产品并将其放在产品队列中,而“消费者”则不断从产品队列中取出产品这里用两个线程模拟“生产者”和“消费者”,用一个数据对象模拟产品没有考虑线程同步的程序:书上P195例9.7本例中由于没有考虑生产者—消费者的的对临界区的访问的冲突,回得到完全错误的结果38 9.4多线程问题-线程同步为了解决这一问题,引入了等待通知(wait/notify)机制:1)在生产者没有生产之前,通知消费者等待;在生产者生产之后,马上通知消费者消费。2)在消费者消费了之后,通知生产者已经消费完,需要生产。见书上P195例9.839 9.4多线程问题-线程同步五、死锁死锁是指两个或多个线程无休止地互相等待对方释放所占据资源的过程。错误的同步往往会引起死锁。为了防止死锁,在进行多线程程序设计时必须遵循如下原则:1)在指定的任务真正需要并发时,才采用多线程来进行程序设计。2)在对象的同步方法中需要调用其他同步方法时必须小心。3)在临界区中的时间应尽可能短,需要长时间运行的任务尽量不要放在临界区中。40 本章小结1.实现线程有两种方法:实现Ruannable接口继承Thread类2.在小应用中通常在start中创建线程3.当新线程被启动时,java调用该线程的run方法,它是Thread的核心.4.线程由五个状态:新建,就绪,运行,阻塞,死亡41 本章小结5.两个或多个线程竞争资源时,需要用同步的方法协调资源.6.多个线程执行时,要用到同步方法,即使用synchronized的关键字设定同步区7.wait和notify起协调作用42

当前文档最多预览五页,下载文档查看全文

此文档下载收益归作者所有

当前文档最多预览五页,下载文档查看全文
温馨提示:
1. 部分包含数学公式或PPT动画的文件,查看预览时可能会显示错乱或异常,文件下载后无此问题,请放心下载。
2. 本文档由用户上传,版权归属用户,天天文库负责整理代发布。如果您对本文档版权有争议请及时联系客服。
3. 下载前请仔细阅读文档内容,确认文档内容符合您的需求后进行下载,若出现内容与标题不符可向本站投诉处理。
4. 下载文档时可能由于网络波动等原因无法下载或下载错误,付费完成后未能成功下载的用户请联系客服处理。
关闭