§ 2.2线程的属性
内容提要
多任务系统中可以支持多个任务的同时执行,而
JAVA语言则对多线程编程提供了全面的支持,为了更有
效,更合理的开发多线程程序,因此需要进一步了解线
程的各种属性,本节包括以下主要内容,
– 线程的生命周期
– 线程优先级
– 线程组
– 守护线程
§ 2.2线程的属性
任务
HNS软件学院开发部在对图书馆管理系统进
行系统分析和概要设计后,进入到系统实现阶段。
用户要求在界面上能够实时显示系统的当前时间,
并且不影响其他功能的正常使用,现指派您完成
该项任务。
基本概念
? 时间片( Time Slice)
– 多任务系统中将计算机的系统资源(主要指 CPU时
间)进行时间上的分割,即将整个工作时间分成一
个个的时间段,每个时间段称为一个时间片。
C P U 时 间
任 务 1
任 务 2
任 务 4
任 务 3
线程的生命周期( Thread Lifecycle)
? 线程的 生命周期 是指一个线程从产生到
消亡的发展过程。
? 线程生命周期的不同阶段称作线程的不同 状态
? 在一个线程的生命周期内可以有五种状态,即
创建( new)、可运行 (runnable)、运行中
( running)、不可运行( not runnable)也称
阻塞( blocked)和死亡( dead)。
线程的生命周期( Thread Lifecycle)
? 线程的生命周期状态转换图
创 建 可 运 行
不 可 运 行 运 行 中
死 亡
s t a r t ( )
1, r u n ( ) 方 法 结 束
2, s t o p ( ) / / 作 废
3, 未 处 理 的 异 常
1, 时 间 片 结 束
2, y i e l d ( )
1, 操 作 系 统 调 度
1, s l e e p ( )
2, w a i t ( )
3, I O 中 断
4, 等 待 锁 定
5, s u s p e n d ( ) / / 作 废
1, 睡 眠 时 间 结 束
2, n o t i f y ( ) 或 n o t i f y A l l ( )
3, I O 中 断 恢 复
4, 解 锁
5, r e s u m e ( ) / / 作 废
线程的生命周期( Thread Lifecycle)
?创建状态 ( new)
?使用 new 运算符创建的线程对象处于创建状态
?新创建的线程对象在调用了 start()方法后, 线程就
从创建状态进入可运行状态 。
线程的生命周期( Thread Lifecycle)
?可运行状态 ( Runnable)
?可运行状态的线程是具备除 CPU运行时间以外的其它各种所
需资源, 但尚未运行的线程, 有时也将可运行状态称为就续态 。
?可运行状态线程来自下列三类情况
?从创建状态进入可运行状态
?从运行状态返回可运行状态
?从阻塞状态返回可运行状态
注意 可运行状态和 Runnable接口没有任何关系
线程的生命周期( Thread Lifecycle)
? 运行状态( Running)
?处于运行状态的线程是真正拥有 CPU使用权的线程
?线程调度程序按照一定的调度原则,从处于可运行状态
的线程队列中选择一个线程,使它获得 CPU的使用权
?处于运行状态的线程将执行线程对象的 run()方法
?一个线程可以从运行状态分别转换到下列三种状态
?从运行状态返回到可运行状态
?从运行状态进入阻塞状态
?线程执行完 run()方法中的所有代码,进入死亡状态
线程的生命周期( Thread Lifecycle)
? 不可运行状态( not Runnable)
?不可运行状态,也称为阻塞状态( Blocked),指因为某
种原因使得线程处于无法运行的状态。
?处于阻塞状态的线程即使拥有 CPU使用时间也无法运行
?进入不可运行状态的原因通常有 5种,
?线程调用 sleep()方法
?线程调用 wait()方法
?线程调用了一个在输入 /输出时中断的操作
?线程试图锁定一个当前被另一个线程锁定了的对象
?由其他线程调用 suspend()方法,将线程挂起
线程的生命周期( Thread Lifecycle)
? 死亡状态( Dead)
?死亡状态是指线程结束其生命周期,进入无法再
次运行的状态。
?有 3类方法可以使线程进入死亡状态,
①自然消亡,即 run()方法中的代码执行完毕;
②由其他线程调用 stop()方法;
③没有捕获的异常事件终止 run()方法的执行,从而
导致线程的突然死亡。
线程的生命周期( Thread Lifecycle)
? Thread.State类中的各状态值
状态值 含义
NEW 处于创建状态的线程
RUNNABLE 处于可运行状态的线程
BLCOKED 处于不可运行状态(阻塞状态)的线程
WAITTING 被其他线程用 wait方法阻塞的线程
TIMED_WAITTING 被其他线程用 wait方法阻塞的线程,其等待时间超时
TERMINATED 处于死亡状态的线程
表 2.2.1
线程的生命周期( Thread Lifecycle)
? 示例 2.2.1 创建一个简单的多线程程序,输出
其生命周期的三种典型状态。
? 代码
? 运行结果
线程的生命周期( Thread Lifecycle)
?线程的调度
方法名 作用
start 启动线程,导致 run方法被调用
run 想要在该线程中执行的代码,Thread类的子类必须覆盖该方法
yield 让当前运行线程放弃本次运行时间
sleep 指定当前运行线程休眠若干时间
join 等待指定线程死亡
isAlive 判断线程是否存活
suspend 将指定线程挂起
resume 将挂起的线程,恢复到可运行状态
stop 停止指定的线程
线程的生命周期( Thread Lifecycle)
?public void start()
该方法负责启动一个线程,使得线程的状态由创
建状态转换为可运行状态,如果不调用 start()方法
线程将永远不会被启动。
?public void run()
该方法中放置需要在该线程中执行的代码,
Thread类的子类只有覆盖该方法,才实现其特定
的功能。
线程的生命周期( Thread Lifecycle)
? run()方法中代码的通常形式如下,
public void run(){
while(true){
… //执行操作
if(退出条件满足 ){
break;
}
}
}
线程的生命周期( Thread Lifecycle)
?public void yield()
放弃当前正在占用的时间片
?public static void sleep(long millis)
sleep()方法将使线程停止执行一段时间,如果在
休眠时间被中断的话将会抛出
InterruptedException
线程的生命周期( Thread Lifecycle)
? 示例 2.2.2 sleep()方法的使用示例
? 代码
? 运行结果
线程的生命周期( Thread Lifecycle)
?public final void join()
将正在运行的线程挂起,直到目标线程运行结
束后才恢复运行。
?public final boolean isAlive()
isAlive()方法用于测试线程是否存活
线程的生命周期( Thread Lifecycle)
练习 2.2.1
创建一个具有 2个线程的多线程程序,使用线程调
度函数,使 2个线程交替输出 5次各自的线程名。
线程的优先级 (Thread Priority)
线程的优先级表示线程的重要程度
?线程优先级的使用原则与操作系统有着密切的联系
?Thread类中定义了三个与优先级有关的静态变量
?MIN_PRIORITY = 1;//最低优先级
?NORM_PRIORITY = 5; //正常优先级
?MAX_PRIORITY = 10;// //最高优先级
?Thread类中与优先级有关的方法有两个
?public final void setPriority(int newPriority)
?public final int getPriority()
线程的优先级 (Thread Priority)
示例 2.2.3 通过线程的优先级来控制线程的运行
代码
运行结果
( a ) ( b )
线程组 (Thread Group)
线程组提供了一个统一管理多个线程而不需单独
管理的机制
–在 JAVA语言中用 java.lang.ThreadGroup类来支持线
程组的实现。
–当多个线程分为一组时,可以用一个方法启动或挂
起线程组中的所有线程。
–每个线程都将属于某个线程组,默认线程组的名字是
main
线程组 (Thread Group)
ThreadGroup类的构造函数和常用方法如下,
①构造函数
public ThreadGroup(String name)
public ThreadGroup(ThreadGroup parent,String name)
其中,name是线程组名,parent是父线程组名
②常用方法
public String getName() //返回当前线程组名
public int activeCount() //获得本组活动线程的数目
publicThreadGroup getParent() //得到当前线程组的父线程组
public void interrupt()//中断线程组中所有线程
public int enumerate(Thread[] list)//将本组活动线程拷贝到数组 list中
线程组 (Thread Group)
示例 2.2.4 应用线程组来控制线程的运行。
代码
运行结果
守护线程 (Daemon Threads)
守护线程,也称后台线程,是指在程序运行的时
候在后台提供一种通用服务的线程
?守护线程不会阻止程序的终止
?要创建一个守护线程则必须在调用它的 start()方法之
前设置
?Thread类中关于守护线程的方法
?public final boolean isDaemon()
?public final void setDaemon(boolean on)
守护线程 (Daemon Threads)
示例 2.2.5 守护线程应用示例
代码
运行结果
任务解决
( 1)创建一个窗口程序
( 2)系统时间的获取
在 Java中使用 java.util.Date类来封装对系统日期和时间的操作。
使用 java.text.SimpleDateFormat来封装对日期数据进行格式化操作。
( 3)定义一个具有线程功能的类,使其可以完成实时更新界面的系统时间的功能
程序类图如下
任务解决
? 运行结果
精练
HNS图书管理系统要求在主窗口的上方,突出显示系统的名
称,HNS图书管理系统”,使其具有闪烁的动态效果,请您
利用本节所学知识完成该项任务。
提示:闪烁效果可以将某一文字每隔一段时间显示一次加以实
现。
小结
?线程的生命周期
?线程的生命周期是指一个线程从产生到消亡的
发展过程。
?线程生命周期的不同阶段称作线程的不同状态。
?在一个线程的生命周期内可以有五种状态,即
创建、可运行、运行中、不可运行 (也称阻塞 )和
死亡。
小结 (续 )
?① 创建状态( new)
一个还没有启动的线程对象处于创建状态,处于创建状
态时,它仅仅只是一个空的线程对象。新创建的线程对
象通过调用 start()方法可以进入可运行状态。
?②可运行状态( Runnable)
可运行状态的线程是尚未运行的线程,它们具备除 CPU
运行时间以外的其它各种所需资源,有时也将可运行状
态称为就续态。
小结 (续 )
?③ 运行状态( Running)
处于运行状态的线程是真正拥有 CPU使用权的线程,线程调度程序按
照一定的线程调度原则,从等待运行的处于可运行状态的线程队列中
选择一个线程,使它获得 CPU的使用权。处于运行状态的线程将执行
run方法。
?④不可运行状态( not Runnable)
不可运行状态,也称为阻塞状态( Blocked),指因为某种原因使得线
程处于无法运行的状态。
?⑤死亡状态( Dead)
死亡状态是指线程结束其生命周期,进入无法再次运行的状态。
小结 (续 )
线程的调度
可以使用 Thread类提供的线程调度方法,
使线程的状态发生改变,常用的重要方法有:
start(),run(),yield(),sleep(),join()和
isAlive()。
小结 (续 )
?线程的优先级 (Thread Priority)
?线程的优先级表示线程的重要程度,
?在默认条件下,一个线程将继承其父线程的优先级。
?线程优先级的使用原则与操作系统有着密切的联系因此在
JAVA中的线程的调度是完全受其所运行平台的操作系统的
线程调度程序控制的,
?可以使用 getPriority()和 setPriority()方法来获取与设定线
程的优先级。
小结 (续 )
?线程组 (Thread Group)
?线程组提供了一个统一管理多个线程而不需单
独管理的机制
?在 JAVA语言中用 java.lang.ThreadGroup类来支
持线程组的实现。
?当多个线程分为一组时,可以用一个方法启动
或挂起线程组中的所有线程。
小结 (续 )
?守护线程 (Daemon Threads)
?守护线程,也称后台线程,是指在程序运行的时候在后
台提供一种通用服务的线程,
?守护线程不会阻止程序的终止。
?使用 setDaemon方法设定一个线程为守护线程。
?要创建一个守护线程必须在调用它的 start()方法之前设
置