Java核心技术卷I:基础知识(原书第8版):14.4 线程属性

来源:互联网 发布:wit.ai api.ai 知乎 编辑:程序博客网 时间:2024/05/19 03:42

铁文整理

14.4 线程属性

    下面将讨论线程的各种属性,其中包括:线程优先级、守护线程、线程组以及处理未捕获异常的处理器。

14.4.1 线程优先级

    Java程序设计语言中,每一个线程有一个优先级。默认情况下,一个线程继承它的父线程的优先级。可以用setPriority方法提高或降低任何一个线程的优先级。可以将优先级设置为在MIN_PRIORITY(在Thread类中定义为1)与MAX_PRIORITY(在Thread类中定义为10)之间的任何值。NORM_PRIORITY被定义为5

    每当线程调度器有机会选择新线程时,它首先选择具有较高优先级的线程。但是,线程优先级是高度依赖于系统的。当虚拟机依赖于宿主机平台的线程实现机制时,Java线程的优先级被映射到宿主机平台的优先级上,优先级个数也许更多,也许更少。

    例如,Windows有7个优先级别。一些Java优先级将映射到相同的操作系统优先级。在SunLinux提供的Java虚拟机,线程的优先级被忽略——所有线程具有相同的优先级。

    初级程序员常常过度使用线程优先级。为优先级而烦恼是事出有因的。不要将程序构建为功能的正确性依赖于优先级。

    警告:如果确实要使用优先级,应该避免初学者常犯的一个错误。如果有几个高优先级的线程没有进入非活动状态,低优先级的线程可能永远也不能执行。每当调度器决定运行一个新线程时,首先会在具有高优先级的线程中进行选择,尽管这样会使优先级的线程完全饿死。

APIjava.lang.Thred 1.0

  • void setPriority(fnt newPriority):设置线程的优先级。优先级必须在MIN_PRIORITY与MAX_PRIORITY之间。—般使用NORM_PRIORITY优先级。

  • static int MIN_PRIORITY:线程的最小优先级。最小优先级的值为1。

  • static int NORM_PRIORITY:线程的默认优先级。缺省优先级为5。

  • static int MAX_PRIORITY:线程的最高优先级。最高优先级的值为10。

  • static void yield():导致当前线程处于让步状态。如果有其他的可运行线程具有至少与此线程同样高的优先级,那么这些线程接下来会被调度。注意,这是一个静态方法。

14.4.2 守护线程

    可以通过调用t.setDaemon(true)将线程转换为守护线程(daemon thread)。这样一个线程没有什么神奇。守护线程的唯一用途是为其他线程提供服务。计时线程就是一个例子,它定时发送“时间嘀嗒”信号给其他线程或清空过时的高速缓存项的线程。当只剩下守护线程时,虚拟机就退出了,由于如果只剩下守护线程,就没有必要继续运行程序了。

    守护线程有时会被初学者错误地使用,他们不打算考虑关机动作。但是这是很危险的。守护线程应该永远不去访问固有资源,如文件、数据库,因为它会在任何时候甚至在一个操作的中间发生中断。

APIjava.lang.Thread 1.0

  • void setDaemon(boolean isDaemon):标识该线程为守护线程或用户线程。这一方法必须在线程启动之前调用。

14.4.3 未捕获异常处理器

    线程的run方法不能抛出任何被检测的异常,但是,不被检测的异常会导致线程终止。在这种情况下,线程就死亡了。

    但是,不需要任何catch子句来处理可以被传播的异常。相反,就在线程死亡之前,异常被传递到一个用于未捕获异常的处理器。

    该处理器必须属于一个实现Thread.UncaughtExceptionHandler接口的类。这个接口只有一个方法。

    void uncaughtException(Thread t, Throwable e)

    Java SE 5.0起,可以用setUncaughtExceptionHandler方法为任何线程安装一个处理器。也可以用Thread类的静态方法setDefaultUncaughtExceptionHandler为所有线程安装一个默认的处理器。替换处理器可以使用日志API发送未捕获异常的报告到日志文件。

    如果不安装默认的处理器,默认的处理器为空。但是,如果不为独立的线程安装处理器,此时的处理器就是该线程的ThreadGroup对象。

    注释:线程组是一个可以统一管理的线程集合。默认情况下,创建的所有线程属于相同的线程组,但是,也可能会建立其他的组。从Java SE 5.0起引入了更好的特性用于线程集合的操作。不要在自己的程序中使用线程组。

    ThreadGroup类实现Thread.UncaughtExceptionHandler接口。它的uncaughtException方法做如下操作:

  1. 如果该线程组有父线程组,那么父线程组的uncaughtException方法被调用。

  2. 否则,如果Thread.getDefaultExceptionHandler方法返回一个非空的处理器,则调用该处理器。

  3. 否则,如果Throwable是ThreadDeath的一个实例,什么都不做。

  4. 否则,线程的名字以及Throwable的栈踪迹被输出到System.err上。

    这是你在程序中肯定看到过许多次的栈踪迹。

APIjava.lang.Thread 1.0

  • static void setDefaultUncaughtExceptionHandler(Thread.UncaughtExceptionHandler handler) 5.0

  • static Thread.UncaughtExceptionHandler getDefaultExceptionHandler() 5.0

  • void setUncaughtExceptionHandler(Thread.UncaughtExceptionHandler handler) 5.0

  • Thread.UncaughtExceptionHandler getUncaughtExceptionHandler() 5.0:设置或获取未捕获异常的处理器。如果没有安装处理器,则将线程组对象作为处理器。

APIjava.lang.Thread.UncaughtExceptionHandler 5.0

  • void uncaughtException(Thread t, Throwable e):当一个线程因未捕获异常而终止,按规定要将客户报告记录到日志中。参数:t:由于未捕获异常而终止的线程;e:未捕获的异常对象。

APIjava.lang.ThreadGroup 1.0

  • void uncaughtException(Thread t, Throwable e):如果有父线程组,调用父线程组的这一方法,或者,如果Thread类有默认处理器,调用该处理器,否则,输出栈踪迹到标准错误流上(但是,如果e是一个ThreadDeath对象,栈踪迹是被禁用的。ThreadDeath对象由stop方法产生,而该方法已经过时)。


0 0
原创粉丝点击