《Java语言程序设计实验指导》电子教案第章.ppt
《《Java语言程序设计实验指导》电子教案第章.ppt》由会员分享,可在线阅读,更多相关《《Java语言程序设计实验指导》电子教案第章.ppt(24页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、第第8章章 多线程编程多线程编程 支持多线程编程是支持多线程编程是JavaJava语言的又一大特色。语言的又一大特色。多线程是相对于进程或单线程而言的,它具有并多线程是相对于进程或单线程而言的,它具有并发性、执行效率高的特点。本章将对发性、执行效率高的特点。本章将对JavaJava中的多中的多线程编程作初步介绍。线程编程作初步介绍。8.1 8.1 多线程编程概述多线程编程概述8.2 8.2 线程的创建线程的创建8.3 8.3 线程的优先级线程的优先级8.4 8.4 线程同步线程同步8.5 8.5 线程间通信线程间通信8.6 8.6 线程的控制线程的控制Return8.1 8.1 多线程编程概述
2、多线程编程概述 本节介绍多线程编程的基础知识,包括多线程的基本节介绍多线程编程的基础知识,包括多线程的基本概念、本概念、JavaJava的线程模型(线程优先级、同步性、消息的线程模型(线程优先级、同步性、消息传递)等方面的内容。传递)等方面的内容。8.1.1 8.1.1 什么是多线程什么是多线程8.1.2 Java8.1.2 Java线程模型线程模型Return8.1.1 8.1.1 什么是多线程什么是多线程 同同 其其 他他 大大 多多 数数 编编 程程 语语 言言 不不 同同,JavaJava内内 置置 支支 持持 多多 线线 程程 编编 程程(multithreaded multithr
3、eaded programmingprogramming)。多多线线程程程程序序包包含含两两条条或或两两条条以以上上并并发发运运行行的的部部分分,把把程程序序中中每每个个这这样样的的部部分分都都叫叫作作一一个个线线程程(threadthread)。每每个个线线程程都都有有独独立立的的执执行行路路径径,因因此此多多线线程程是是多多任任务务处处理理的的一一种种特特殊殊形式。形式。读读者者可可能能知知道道多多任任务务处处理理,它它实实际际上上被被所所有有的的现现代代操操作作系系统统所所支支持持。然然而而,多多任任务务处处理理有有两两种种截截然然不不同同的的类类型型:基基于于进进程程的的和和基基于于线
4、线程程的的。搞搞清清楚楚两两者者的的区区别别是是很很重重要要的的。对对大大多多数数读读者者来来说说,基基于于进进程程的的多多任任务务处处理理是是更更熟熟悉悉的的形形式式。进进程程(processprocess)本本质质上上是是一一个个执执行行的的程程序序。因因此此基基于于进进程程的的多多任任务务处处理理的的特特点点是是允允许许你你的的计计算算机机同同时时运运行行两两个个或或更更多多的的程程序序。举举例例来来说说,基基于于进进程程的的多多任任务务处处理理使使你你在在运运用用文文本本编编辑辑器器的的时时候候可可以以同同时时运运行行JavaJava编编译译器器。在在基基于于进进程程的的多多任任务务处
5、处理理中中,程程序是调度程序所分派的最小代码单位。序是调度程序所分派的最小代码单位。而而在在基基于于线线程程(thread-basedthread-based)的的多多任任务务处处理理环环境境中中,线线程程是是最最小小的的执执行行单单位位。这这意意味味着着一一个个程程序序可可以以同同时时执执行行两两个个或或者者多多个个任任务务的的功功能能。例例如如,一一个个文文本本编编辑辑器器可可以以在在打打印印的的同同时时格格式式化化文文本本。所所以以,多多进程程序处理进程程序处理“大图片大图片”,而多线程程序处理细节问题。,而多线程程序处理细节问题。Return多线程程序比多进程程序需要更少的管理费用。进
6、程是重量级的任务,需要分配给它们独立的地址空间。进程间通信是昂贵和受限的。进程间的转换也是很需要花费的。另一方面,线程是轻量级的选手。它们共享相同的地址空间并且共同分享同一个进程。线程间通信是便宜的,线程间的转换也是低成本的。当Java程序使用多进程任务处理环境时,多进程程序不受Java的控制,而多线程则受Java控制。多线程可帮助你编写出CPU最大利用率的高效程序,使得空闲时间保持最低。这对Java运行的交互式的网络互连环境是至关重要的,因为空闲时间是公共的。例如,网络的数据传输速率远低于计算机处理能力,而本地文件系统资源的读写速度也远低于CPU的处理能力。当然,用户输入也比计算机慢很多。在
7、传统的单线程环境中,程序必须等待每一个这样的任务完成以后才能执行下一步尽管CPU有很多空闲时间。多线程使你能够获得并充分利用这些空闲时间。8.1.2 Java8.1.2 Java线程模型线程模型 Java Java运行系统在很多方面依赖于线程,所有的类库设计都运行系统在很多方面依赖于线程,所有的类库设计都考虑到多线程。实际上,考虑到多线程。实际上,JavaJava使用线程来使整个环境异步。这使用线程来使整个环境异步。这有利于通过防止有利于通过防止CPUCPU循环的浪费来减少无效部分。循环的浪费来减少无效部分。为为更更好好地地理理解解多多线线程程环环境境的的优优势势,我我们们可可以以将将它它与与
8、它它的的对对照照物物相相比比较较。单单线线程程系系统统的的处处理理途途径径是是使使用用一一种种叫叫作作轮轮询询的的事事件件循循环环方方法法。在在该该模模型型中中,单单线线程程控控制制在在一一无无限限循循环环中中运运行行,轮轮询询一一个个事事件件序序列列来来决决定定下下一一步步做做什什么么。一一旦旦轮轮询询装装置置返返回回信信号号表表明明已已准准备备好好读读取取网网络络文文件件,事事件件循循环环调调度度控控制制管管理理到到适适当当的的事事件件处处理理程程序序。直直到到事事件件处处理理程程序序返返回回,系系统统中中没没有有其其他他事事件件发发生生。这这就就浪浪费费了了CPUCPU时时间间。这这导导
9、致致了了程程序序的的一一部部分分独独占占了了系系统统,阻阻止止了了其其他他事事件件的的执执行行。总总的的来来说说,单单线线程程环环境境,当当一一个个线线程程因因为为等等待待资资源源时时阻阻塞塞(blockblock,挂挂起起执执行行),整整个个程程序序停停止运行。止运行。Java多线程的优点就在于取消了主循环/轮询机制。一个线程可以暂停而不影响程序的其他部分。例如,当一个线程从网络读取数据或等待用户输入时产生的空闲时间可以被利用到其他地方。多线程允许活的循环在每一帧间隙中沉睡一秒而不暂停整个系统。在Java程序中出现线程阻塞,仅有一个线程暂停,其他线程继续运行。线程存在多种状态。线程可以正在运
10、行(running),只要获得了CPU时间它就可以运行;运行的线程可以被挂起(suspend),并临时中断它的执行;一个挂起的线程可以被恢复(resume),允许它从停止的地方继续运行;一个线程可以在等待资源时被阻塞(block);在任何时候,线程可以被终止(terminate),这将立即中断运行。一旦终止,线程不能被恢复。线程的各状态间关系见教材P190页图8-1所示。下面简要介绍与下面简要介绍与下面简要介绍与下面简要介绍与JavaJavaJavaJava线程相关的几个概念线程相关的几个概念线程相关的几个概念线程相关的几个概念 JavaJava给给每每个个线线程程安安排排优优先先级级以以决决
11、定定与与其其他他线线程程比比较较时时该该如如何何对对待待该该线线程程。线线程程优优先先级级是是详详细细说说明明线线程程间间优优先先关关系系的的整整数数。作作为为绝绝对对值值,优优先先级级是是毫毫无无意意义义的的;当当只只有有一一个个线线程程时时,优优先先级级高高的的线线程程并并不不比比优优先先级级低低的的线线程程运运行行的的快快。相相反反,线线程程的的优优先先级级是是用用来来决决定定何何时时从从一一个个运运行行的的线线程程切切换换到到另另一一个个。这这叫叫“上上下下文文转转换换”(context context switchswitch)。决决定定上上下下文文转转换换发发生生的的规则很简单:规
12、则很简单:l l线线程程可可以以自自动动放放弃弃控控制制。在在I/OI/O未未决决定定的的情情况况下下,睡睡眠眠或或阻阻塞塞由由明明确确的的让让步步来来完完成成。在在这这种种假假定定下下,所所有有其其他他的的线线程程被被检检测测,准准备备运运行行的的最最高优先级线程被授予高优先级线程被授予CPUCPU。l l线线程程可可以以被被高高优优先先级级的的线线程程抢抢占占。在在这这种种情情况况下下,低低优优先先级级线线程程不不主主动动放放弃弃,处处理理器器只只是是被被先先占占无无论论它它正正在在干干什什么么处处理理器器被被高高优优先先级级的的线线程程占占据据。基基本本上上,一一旦旦高高优优先先级级线线
13、程程要要运运行行,它它就就执执行行。这这叫叫做做有有优先级的多任务处理。优先级的多任务处理。当两个相同优先级的线程竞争当两个相同优先级的线程竞争CPUCPU周期时,情形有一点复杂。对于周期时,情形有一点复杂。对于WindowsWindows这样的操作系统,等优先级的线程是在循环模式下自动划分时间的。这样的操作系统,等优先级的线程是在循环模式下自动划分时间的。对于其他一些非对于其他一些非WindowsWindows操作系统而,如操作系统而,如Solaris 2.xSolaris 2.x,等优先级线程相对,等优先级线程相对于它们的对等体自动放弃。如果不这样,其他的线程就不会运行。于它们的对等体自动
14、放弃。如果不这样,其他的线程就不会运行。1 1线程优先级线程优先级2 2 2 2同步性同步性同步性同步性 由由于于多多线线程程在在程程序序中中引引入入了了一一个个异异步步行行为为,故故在在需需要要的的时时候候必必须须有有加加强强同同步步性性的的方方法法。举举例例来来说说,如如果果你你希希望望两两个个线线程程相相互互通通信信并并共共享享一一个个复复杂杂的的数数据据结结构构,例例如如链链表表序序列列,就就需需要要某某些些方方法法来来确确保保它它们们没没有有相相互互冲冲突突。也也就就是是说说,你你必必须须防防止止一一个个线线程程写写入入数数据据而而另另一一个个线线程程正正在在读读取取链链表表中中的的
15、数数据据。为为此此,JavaJava在在进进程程间间同同步步性性的的老老模模式式基基础础上上实实 行行 了了 另另 外外 的的 一一 种种 方方 法法:管管 程程(monitormonitor)。管管 程程 是是 一一 种种 由由C.A.R.HoareC.A.R.Hoare首首先先定定义义的的控控制制机机制制。你你可可以以把把管管程程想想象象成成一一个个仅仅控控制制一一个个线线程程的的小小盒盒子子。一一旦旦线线程程进进入入管管程程,所所有有线线程程必必须须等等待待直直到到该该线线程程退退出出了了管管程程。用用这这种种方方法法,管管程程可可以以用用来来防防止止共共享享的的资资源源被被多多个个线线
16、程操纵。程操纵。很很多多多多线线程程系系统统将将管管程程作作为为程程序序必必须须明明确确的的引引用用和和操操作作的的对对象象。但但JavaJava提提供供一一个个清清晰晰的的解解决决方方案案,不不提提供供“Monitor”“Monitor”类类;相相反反,每每个个对对象象都都拥拥有有自自己己的的隐隐式式管管程程,当当对对象象的的同同步步方方法法被被调调用用时时管管程程自自动动载载入入。一一旦旦一一个个线线程程包包含含在在一一个个同同步步方方法法中中,没没有有其其他他线线程程可可以以调调用用相相同同对对象象的的同同步步方方法法。这这就就使使你你可可以以编编写写非非常常清清晰晰和和简简洁洁的的多多
17、线线程程代代码码,因为同步支持是语言内置的。因为同步支持是语言内置的。3 3 3 3消息传递消息传递消息传递消息传递 当当把把程程序序分分成成若若干干线线程程后后,就就要要定定义义各各线线程程之之间间的的联联系系。用用大大多多数数其其他他语语言言规规划划时时必必须须依依赖赖于于操操作作系系统统来来确确立立线线程程间间通通信信,这这样样当当然然要要增增加加花花费费。然然而而,JavaJava提提供供了了多多线线程程间间谈谈话话清清洁洁的的、低低成成本本的的途途径径通通过过调调用用所所有有对对象象都都有有的的预预先先确确定定的的方方法法。JavaJava的的消消息息传传递递系系统统允允许许一一个个
18、线线程程进进入入一一个个对对象象的的一一个个同同步步方方法法,然然后后在在那那里里等等待待,一一直直等等到其他线程明确通知它出来。到其他线程明确通知它出来。Return Java的多线程系统建立于Thread类、方法以及共伴接口Runnable基础上。Thread类封装了线程的执行。既然不能直接引用运行着的线程的状态,就要通过它的代理处理它。于是Thread 实例产生了。为创建一个新的线程,程序中必须扩展Thread 或实现Runnable接口。Thread类定义了好几种方法来帮助管理线程,见教材P192页表8-1中所列。4 4ThreadThread类和类和RunnableRunnable接
19、口接口8.2 8.2 线程的创建线程的创建 本节介绍在本节介绍在JavaJava中如何创建线程。主要内容包括主中如何创建线程。主要内容包括主线程、多线程的创建、相关方法的使用等。线程、多线程的创建、相关方法的使用等。8.2.1 8.2.1 关于主线程关于主线程8.2.2 8.2.2 创建一个线程创建一个线程8.2.3 8.2.3 创建多线程创建多线程8.2.4 8.2.4 使用使用isAlive()isAlive()和和join()join()Return8.2.1 8.2.1 关于主线程关于主线程 当当JavaJava程程序序启启动动时时,一一个个线线程程立立刻刻运运行行,该该线线程程通通常
20、常就就叫叫做做程程序序的的主主线线程程(main main threadthread),因为它是程序开始时就执行的。主线程的重要性主要体现在两方面:),因为它是程序开始时就执行的。主线程的重要性主要体现在两方面:l l它是产生其他子线程的线程;它是产生其他子线程的线程;l l通常它必须最后完成执行,因为它执行各种关闭动作。通常它必须最后完成执行,因为它执行各种关闭动作。尽尽管管主主线线程程在在程程序序启启动动时时自自动动创创建建,但但它它可可以以由由一一个个ThreadThread对对象象控控制制。为为此此,必必须须调调用用方方法法currentThread()currentThread()获
21、获得得它它的的一一个个引引用用,currentThread()currentThread()是是ThreadThread类类的的公公有的静态成员。它的一般形式如下有的静态成员。它的一般形式如下staticThreadcurrentThread()staticThreadcurrentThread()该该方方法法返返回回一一个个调调用用它它的的线线程程的的引引用用。一一旦旦获获得得主主线线程程的的引引用用,就就可可以以像像控控制制其其他线程那样控制主线程。他线程那样控制主线程。下面我们考察一下教材下面我们考察一下教材P192P192 193193页的程序代码。页的程序代码。在上面的程序中,当前线
22、程(当然是主线程)的引用通过调用在上面的程序中,当前线程(当然是主线程)的引用通过调用currentThread()currentThread()获得,该引用保存在局部变量获得,该引用保存在局部变量t t中。然后,程序显示了线程的信息。接着,程序调用中。然后,程序显示了线程的信息。接着,程序调用setNamesetName()()改变线程的内部名称,线程信息又被显示。然后,一个循环数从改变线程的内部名称,线程信息又被显示。然后,一个循环数从5 5开始递减,每数开始递减,每数一次暂停一秒。暂停是由一次暂停一秒。暂停是由sleep()sleep()方法来完成的,方法来完成的,sleep()slee
23、p()语句明确规定延迟时间是语句明确规定延迟时间是1 1毫秒。请读者注意循环外的毫秒。请读者注意循环外的try/catchtry/catch块。块。ThreadThread类的类的sleep()sleep()方法可能引发一个方法可能引发一个InterruptedExceptionInterruptedException异常,这种情形会在其他线程想要打搅沉睡线程时发生。本异常,这种情形会在其他线程想要打搅沉睡线程时发生。本例只是打印了它是否被打断的消息。在实际的程序中,必须灵活处理此类问题。例只是打印了它是否被打断的消息。在实际的程序中,必须灵活处理此类问题。Return8.2.2 8.2.2
24、创建一个线程创建一个线程大多数情况,通过实例化一个大多数情况,通过实例化一个ThreadThread对象来创建一个线程。对象来创建一个线程。JavaJava定义了两种方式:定义了两种方式:l l实现实现Runnable Runnable 接口;接口;l l以继承以继承ThreadThread类的方式。类的方式。创建线程最简单的方法就是创建一个实现Runnable 接口的类,Runnable抽象了一个执行代码单元。可以通过实现Runnable接口的方法创建每一个对象的线程。为实现 Runnable 接口,一个类仅需实现一个run()的简单方法,该方法声明如下:publicvoidrun()在ru
25、n()中,可以定义代码来构建新的线程。重要的是:run()方法能够像主线程那样调用其他方法,引用其他类,声明变量。仅有的不同是:run()在程序中确立另一个并发的线程执行入口。当run()返回时,该线程结束。在已经创建了实现Runnable接口的类以后,需要在类内部实例化一个Thread类的对象。Thread 类定义了好几种构造函数。我们会用到的如下:Thread(RunnablethreadOb,StringthreadName)在该构造函数中,threadOb是一个实现Runnable接口类的实例。这定义了线程执行的起点,新线程的名称由threadName定义。建立新的线程后,它并不运行直
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Java语言程序设计实验指导 Java 语言程序设计 实验 指导 电子 教案
限制150内