Java多线程(五)、多线程其他知识简要介绍

一、线程组

[java]  view plain  copy
  1. /** 
  2.  * A thread group represents a set of threads. In addition, a thread  
  3.  * group can also include other thread groups. The thread groups form  
  4.  * a tree in which every thread group except the initial thread group  
  5.  * has a parent.  
  6.  * <p> 
  7.  * A thread is allowed to access information about its own thread  
  8.  * group, but not to access information about its thread group's  
  9.  * parent thread group or any other thread groups.  
  10.  * 
  11.  * @author  unascribed 
  12.  * @version 1.66, 03/13/08 
  13.  * @since   JDK1.0 
  14.  */  
一个线程组代表了一系列的线程。并且,一个线程组可以包括其他的线程组。除了初始线程组外,每个线程组都有一个父线程组,类似于树的结构。

一个线程可以访问它所在线程组的信息, 不可以访问它父线程组和其他线程组的信息。

 从这段话中可以大概明白线程组的概念,所有的线程和线程组构成一个树的结构,如下:



查看Thread的API,可以看到,创建一个线程可以指定它的线程组和不指定线程组。如果指定其所属的线程组,那么该线程组是创建它的线程所属线程组的子线程组。如果不指定线程组,则属于默认情况,该线程和创建它的线程在同一个线程组。

以上面的图举个简单的例子:

如果main线程创建了Thread1线程,没有指定Thread1所在的线程组,那么Thread1就默认和main线程属于同一个线程组,即系统线程组。

如果main线程创建了Thread3线程,没指定Thread3所在的线程组为线程组1,那么线程组1就属于系统线程组,和main线程在树结构中平级。


一旦某个线程加入了指定线程组之后,该线程将一直属于该线程组,直到该线程死亡,线程运行中途不能改变它所属的线程组。因为指定线程所在线程组是在创建线程的视乎完成的,所以之后不能再修改它所在的线程组。

下面是ThreadGroup的方法摘要

 

方法摘要
 intactiveCount()
          返回此线程组中活动线程的估计数。
 intactiveGroupCount()
          返回此线程组中活动线程组的估计数。
 booleanallowThreadSuspension(boolean b)
          已过时。 此调用的定义取决于 suspend(),它被废弃了。更进一步地说,此调用的行为从不被指定。
 voidcheckAccess()
          确定当前运行的线程是否有权修改此线程组。
 voiddestroy()
          销毁此线程组及其所有子组。
 intenumerate(Thread[] list)
          把此线程组及其子组中的所有活动线程复制到指定数组中。
 intenumerate(Thread[] list, boolean recurse)
          把此线程组中的所有活动线程复制到指定数组中。
 intenumerate(ThreadGroup[] list)
          把对此线程组中的所有活动子组的引用复制到指定数组中。
 intenumerate(ThreadGroup[] list, boolean recurse) 
          把对此线程组中的所有活动子组的引用复制到指定数组中。
 intgetMaxPriority()
          返回此线程组的最高优先级。
 StringgetName()
          返回此线程组的名称。
 ThreadGroupgetParent()
          返回此线程组的父线程组。
 voidinterrupt()
          中断此线程组中的所有线程。
 booleanisDaemon()
          测试此线程组是否为一个后台程序线程组。
 booleanisDestroyed()
          测试此线程组是否已经被销毁。
 voidlist()
          将有关此线程组的信息打印到标准输出。
 booleanparentOf(ThreadGroup g)
          测试此线程组是否为线程组参数或其祖先线程组之一。
 voidresume()
          已过时。 此方法只用于联合 Thread.suspend 和 ThreadGroup.suspend 时,因为它们所固有的容易导致死锁的特性,所以两者都已废弃。有关详细信息,请参阅Thread.suspend()
 voidsetDaemon(boolean daemon)
          更改此线程组的后台程序状态。
 voidsetMaxPriority(int pri)
          设置线程组的最高优先级。
 voidstop()
          已过时。 此方法具有固有的不安全性。有关详细信息,请参阅 Thread.stop()
 voidsuspend()
          已过时。 此方法容易导致死锁。有关详细信息,请参阅 Thread.suspend()
 StringtoString()
          返回此线程组的字符串表示形式。
 voiduncaughtException(Thread t,Throwable e) 
          当此线程组中的线程因为一个未捕获的异常而停止,并且线程没有安装特定 Thread.UncaughtExceptionHandler 时,由 Java Virtual Machine 调用此方法。
 


二、线程组与未处理的异常

从JDK1.5开始,Java加强了线程的异常处理,如果线程执行过程中抛出了一个未处理的异常,JVM在结束该线程之前会自动查找是否有对应的Thread.UncaughtExceptionHandler对象,如果找到该处理器对象,将会调用该对象的uncaughtException(Thread t,Throwable e)方法来处理该异常。

Thread.UncaughtExceptionHandler是Thread类的一个内部公共静态接口,该接口内只有一个方法:

void uncaughtException(Thread t,Throwable t),该方法中的t代表出现异常的线程,而e代表该线程抛出的异常。

Thread类提供了两个方法来设置异常处理器:

public static void setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler eh)

线程类的所有线程实例设置默认的异常处理器

public void setUncaughtExceptionHandler(UncaughtExceptionHandler eh)

为指定线程的实例设置异常处理器

ThreadGroup类实现了Thread.UncaughtExceptionHandler接口,所以每个线程所属的线程组将会作为默认的异常处理器。当一个线程抛出未处理的异常时,JVM会首先查找该异常对应的异常处理器(setUncaughtExceptionHandler方法设置的异常处理器),如果找到该异常处理器,将调用该异常处理器处理该异常,否则,JVM将会调用该线程所属的线程组对象的uncaughtException方法来处理该异常,线程组处理异常的流程如下:

1)、如果该线程组有父线程组,则调用父线程组的uncaughtException方法来处理该异常

2)、否则,如果该线程实例所属的线程类有默认的异常处理器(由setDefaultUncaughtExceptionHandler方法设置的异常处理器),那么就调用该异常处理器来处理该异常

3)、否则,将异常调试栈的信息打印到System.err错误输出流,并结束该线程。

看下面的例子:

[java]  view plain  copy
  1. class MyHandler implements Thread.UncaughtExceptionHandler{  
  2.     @Override  
  3.     public void uncaughtException(Thread t, Throwable e) {  
  4.         System.out.println("出现了异常");  
  5.         e.printStackTrace();  
  6.     }  
  7. }  
  8. public class Test{  
  9.     public static void main(String[] args) {  
  10.         Thread.currentThread().setUncaughtExceptionHandler(new MyHandler());  
  11.         int a=1/0;  
  12.     }  
  13. }  

在主线程中设置了异常处理器,最后捕获了异常。



三、Callable和Future

参考:http://lavasoft.blog.51cto.com/62575/222082


四、volatile关键字

参考:http://lavasoft.blog.51cto.com/62575/222076


五、显示同步锁

参考:http://lavasoft.blog.51cto.com/62575/222084
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值