多线程与异常处理PPT

上传人:y****8 文档编号:138088621 上传时间:2020-07-13 格式:PPT 页数:72 大小:741.50KB
返回 下载 相关 举报
多线程与异常处理PPT_第1页
第1页 / 共72页
多线程与异常处理PPT_第2页
第2页 / 共72页
多线程与异常处理PPT_第3页
第3页 / 共72页
多线程与异常处理PPT_第4页
第4页 / 共72页
多线程与异常处理PPT_第5页
第5页 / 共72页
点击查看更多>>
资源描述

《多线程与异常处理PPT》由会员分享,可在线阅读,更多相关《多线程与异常处理PPT(72页珍藏版)》请在金锄头文库上搜索。

1、2020/7/13 14:27,1,第七章多线程与异常处理,武汉大学计算机学院计算机应用系,第 2 页,深入理解多线程的基本概念 熟练掌握创建线程的两种基本方法 熟练处理线程的同步问题和死锁问题 深入理解异常的基本概念 熟悉和掌握Java平台定义异常类 熟练掌握创建自定义异常类的方法 熟练运用异常处理的手段编写鲁棒的Java程序,本章学习要点,2020/7/13 14:27,3,7.1 多线程的基本概念,第 4 页,7.1.1 多任务,多任务 多任务是计算机操作系统同时运行几个程序或任务的能力。现代操作系统都支持多任务,多任务有两种形式: 基于进程的多任务 基于线程的多任务 程序、进程和线程

2、程序是一段静态的代码,它是应用程序执行的蓝本。 进程是程序的一次动态执行过程,它对应了从代码加载、执行到执行完毕的一个完整过程。程序可以被多次加载到系统的不同内存区域分别执行,形成不同的进程。 线程是进程内部的一个顺序执行控制流。 一个进程在执行过程中,可以产生多个线程同时执行。每个线程也有自己产生、存在和消亡的过程。,第 5 页,7.1.2 线程与多线程,线程和进程的区别: 从逻辑的观点来看,多线程意味着一个程序的多行语句同时执行,但是多线程并不等于多次启动一个程序,操作系统也不会把每个线程当作独立的进程来对待。 两者的层次不同,进程是由操作系统来管理的,而线程则是在一个程序(进程)内部存在

3、的。 不同进程的代码、内部数据和状态都是完全独立的,进程之间进行切换和通信的开销很大。 线程本身的数据通常只有寄存器数据以及程序执行时使用的堆栈,一个程序内的多个线程是共享同一内存空间和系统资源,线程的切换开销小,线程之间的通信很容易。,第 6 页,7.1.2 线程与多线程,程序区段,程序区段,第 7 页,7.1.3 Java对多线程的支持,虚拟CPU,封装在java.lang.Thread类中,它控制着整个线程的运行; 执行代码,传递给Thread类,由Thread类控制顺序执行; 处理的数据,传递给Thread类,是在代码执行过程中所要处理的数据。,对多线程的综合支持是Java语言的一个重

4、要特色,它提供了Thread类来实现多线程。在Java中,线程可以认为是由三部分组成的:,第 8 页,7.1.4 线程的状态,每个Java程序都有一个缺省的主线程,对于Application,主线程是执行main()方法的线程;对于Applet,主线程是通过浏览器加载并执行Java小程序的线程。 多线程应用的实质就是在主线程之外,定义了一个或多个新的线程。 Java使用Thread类及其子类表示线程。一个线程的生命周期中,线程的状态表示了线程正在进行的活动以及在这段时间内线程能完成的任务。,第 9 页,7.1.4 线程的状态,一个线程在它的生命周期中通常要经历五种状态。 新建(Newborn)

5、 就绪(Runnable) 运行(Running),阻塞(Blocked) 死亡(Dead),第 10 页,7.1.4 线程的状态,新建状态(Newborn) 当创建了一个新的线程对象时,它就处于新建状态,此时它仅仅是一个空的线程对象,系统不为它分配资源。处于这种状态时只能启动Start()或终止Stop()该线程,调用除这两种以外的其它方法都会失败并且会引起非法状态异常IllegalThreadStateException(对于其它状态,若所调用的方法与状态不符,都会引起非法状态异常)。,第 11 页,7.1.4 线程的状态,就绪状态(Runnable) 当线程处于新建状态时,可以调用sta

6、rt()方法来启动它,产生运行这个线程所需的系统资源,安排其运行,并调用线程体run()方法,这样该线程就处于就绪( Runnable )状态。 这一状态并不是运行状态(Running ),因为线程也许实际上并未真正运行。由于很多计算机都是单处理器的,所以要在同一时刻运行所有的处于就绪状态的线程是不可能的,Java运行系统必须通过调度来保证这些线程共享处理器。,第 12 页,Thread myThread = new MyThreadClass(); myThread.start(); try myThread.sleep(10000); catch (InterruptedException

7、 e) ,7.1.4 线程的状态,阻塞状态(Blocked) 线程处于可运行状态时,当下面四种情况发生,线程就进入不可运行状态: 调用了休眠方法sleep( )或yield() 方法; 调用了挂起方法suspend( ); 为等候一个条件变量,线程调用等待方法wait(); 输入输出流中发生线程阻塞。,第 13 页,7.1.4 线程的状态,对于这四种使得线程处于不可运行状态的情况,都有特定的方法使线程返回可运行状态: 如果线程处于休眠状态中,sleep()方法中的参数为休眠时间,当这个时间过去后,线程即为可运行的; 如果线程在等待条件变量,那么要停止等待的话,需要该条件变量所在的对象调用not

8、ify()或notifyAll()方法; 如果在I/O流中发生线程阻塞,则特定的I/O指令将结束这种不可运行状态。 需要注意的是每种方法都仅仅对相应的状态才有作用,例如当一个线程休眠并且休眠时间还没有结束时,调用其他方法是无效的,并且还会引起非法状态异常。,第 14 页,7.1.4 线程的状态,死亡状态(Dead) 线程的终止一般可通过两种方法实现:自然撤消或强行终止。 自然撤消是指从线程的run( )方法正常结束退出,如果希望线程正常终止,一般可使用某种手段来使线程中的run()方法结束执行。 调用线程的实例方法stop( )则可以强制停止当前线程。既可以在其他线程中调用该线程的stop()

9、方法来终止,也可以由线程自己调用stop()方法,自我终止。但这个方法已在JDK2中建议不再使用,应当避免使用。,第 15 页,7.1.5 线程的优先级,每个线程各自任务的重要程度不同而可能有不同的优先级。 Java提供一个线程调度器来监控程序中进入就绪状态的所有线程。线程调度器按照线程的优先级决定调度线程的执行。 多个线程运行时,具有高优先级的线程会在较低优先级的线程之前得到执行。 线程的调度是抢先式的,一个具有更高优先级的线程进入可执行状态,则该高优先级的线程会被立即调度执行。 同一优先级的线程,采取先进先出的原则由操作系统按时间片轮转方式或独占方式来分配线程的执行时间。,第 16 页,7

10、.1.5 线程的优先级,线程的优先级用数字来表示,范围从1到10,Thread类有三个关于优先级的静态常量: MIN_PRIORITY=1 MAX_ PRIORITY=10 NORM_ PRIORITY=5 对应于一个新线程,系统会遵循以下原则: 新线程将继承创建它的父线程的优先级。 一般情况下,线程具有普通优先级。 用户可以根据需要,通过setPriority()方法来修改优先级。,第 17 页,7.1.6 线程的主要方法,Tread类综合了Java程序中一个线程所需要拥有的属性和方法,主要有: public Thread(Runnable target, String name) targ

11、et是线程体run()方法所在的对象; name是线程的名称。 target必须实现接口Runnable。在接口Runnable中只定义了一个方法void run()作为线程体。任何实现接口Runnable的对象都可以作为一个线程的目标对象。 start()方法:启动线程,使线程由新建状态转为就绪状态; run()方法:定义该线程的操作,run()方法比较特殊,它可以被系统自动识别并执行。,第 18 页,7.1.6 线程的主要方法,sleep()方法:使线程进入到休眠状态。让其它线程得到机会执行。sleep()会抛出异常InterruptedException ,必须捕获。 isAlive()

12、方法:可以用来判断线程目前是否正在执行状态中。如果线程已被启动并且未被终止,那么isAlive( )返回true,但该线程是可运行或是不可运行的,需要作进一步的判断。如果返回false,则该线程是新创建或是已被终止的(同样也需要作进一步的判断)。 join()方法:等待另一个线程终止,即接着另一个线程执行。 yield()方法:将执行的权力交给其它优先级相同的线程,自己到可运行线程队列的最后等待,若队列空,该方法无效。,第 19 页,7.2 线程的使用方法,Java中编程实现多线程有两种方式: 由Thread类派生子类创建线程类; 通过实现Runnable接口创建线程类。 两种方法都要使用到J

13、ava.lang中的Thread类及其方法来实现。当生成一个Thread对象之后,就产生了一个线程,通过该对象,可以启动线程、终止线程、或者暂时休眠等。 Thread类本身只是线程的虚拟CPU,线程所执行的代码(或者说线程所要完成的功能)是通过方法run()来完成的,run()方法称为线程体。在一个线程被建立并初始化以后,Java的运行时系统就自动调用run( )方法,完成线程要达到的目标。,第 20 页,7.2.1 通过继承Thread类构造线程,线程的创建与启动 通过继承Thread类创建并执行一个线程,须完成下列步骤: (1)创建一个类扩展Thread类(extends Thread)。

14、 (2)用要在这个线程中执行的代码编写run()方法,覆盖Thread类的run()方法。 (3)用关键字new创建所定义的线程类的一个对象。 (4)调用该对象的start()方法启动线程。 由于Java只支持单继承,所定义的类不能再继承其他类。 【例7.1】 创建一个Thread类的子类,显示18这8个数字,然后在另一个类中建立这个Thread类的3个对象来测试它,看执行时会发生什么现象。,第 21 页,7.2.1 通过继承Thread类构造线程,终止线程执行的技巧 如下步骤实现一种简单的机制,可在任何时候终止线程: 编写一个类扩展Thread类。 增加一个布尔变量running到这个类中,

15、并初始化为false。 覆盖start()方法:置running为true,然后调用super.start()。 提供一个public方法halt(),它将running变量置为false。 在run()方法中使用类似于下例的while循环: public void run() while (running) /* 线程要执行的代码 */ 如果halt()方法被调用,就会引起run()方法终止执行,结束该线程。,第 22 页,7.2.1 通过继承Thread类构造线程,【例7.2】 模拟一个笼子内有二十个鸟在里面移动,每个“鸟”是一个Thread对象。“笼子”是一个Frame。它包含有3个按钮

16、,用于启动、终止“鸟”和退出程序。 “鸟”类可按如下步骤去实现: 扩展Thread,这样就是独立执行的线程,即鸟可独立行走。 按上述终止线程的技巧,使得鸟类可在任何时刻停止执行。 设置两个域x,y,作为鸟的当前坐标。 编写move()方法,重新移动鸟到一个新的x,y坐标,在方法中重新计算它的坐标,使它产生移动效果。 由于有多个移动的鸟,所以在每个线程的run()方法中应该调用sleep()方法,让出时间使操作系统去移动其他的鸟。,第 23 页,7.2.1 通过继承Thread类构造线程,【扩展海底世界】 模拟多条鱼在海底游动,每个“鱼”是一个Thread类。“海底”是扩展Frame的类,Frame内粘贴一副精美的海底画面。在前面的例子中去掉按钮,用鼠标的双击来启动、终止“鱼”的游动。,第 24 页,7.2.2 通过实现Runnable接口来构造线程,Runnable接口 Runnable接口只有一个方法run(),所有实现Runnabel接口的用户类都必须实现这个run()方法,即为它编写具体的方法体代码。 在许多情况下,一个类已经扩展了Frame或Applet,由

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

当前位置:首页 > 高等教育 > 其它相关文档

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