一、线程组

  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的方法摘要

方法摘要
 int activeCount()
          返回此线程组中活动线程的估计数。
 int activeGroupCount()
          返回此线程组中活动线程组的估计数。
 boolean allowThreadSuspension(boolean b)
          已过时。 此调用的定义取决于 suspend(),它被废弃了。更进一步地说,此调用的行为从不被指定。
 void checkAccess()
          确定当前运行的线程是否有权修改此线程组。
 void destroy()
          销毁此线程组及其所有子组。
 int enumerate(Thread[] list)
          把此线程组及其子组中的所有活动线程复制到指定数组中。
 int enumerate(Thread[] list, boolean recurse)
          把此线程组中的所有活动线程复制到指定数组中。
 int enumerate(ThreadGroup[] list)
          把对此线程组中的所有活动子组的引用复制到指定数组中。
 int enumerate(ThreadGroup[] list, boolean recurse) 
          把对此线程组中的所有活动子组的引用复制到指定数组中。
 int getMaxPriority()
          返回此线程组的最高优先级。
 String getName()
          返回此线程组的名称。
 ThreadGroup getParent()
          返回此线程组的父线程组。
 void interrupt()
          中断此线程组中的所有线程。
 boolean isDaemon()
          测试此线程组是否为一个后台程序线程组。
 boolean isDestroyed()
          测试此线程组是否已经被销毁。
 void list()
          将有关此线程组的信息打印到标准输出。
 boolean parentOf(ThreadGroup g)
          测试此线程组是否为线程组参数或其祖先线程组之一。
 void resume()
          已过时。 此方法只用于联合 Thread.suspend 和 ThreadGroup.suspend 时,因为它们所固有的容易导致死锁的特性,所以两者都已废弃。有关详细信息,请参阅Thread.suspend()
 void setDaemon(boolean daemon)
          更改此线程组的后台程序状态。
 void setMaxPriority(int pri)
          设置线程组的最高优先级。
 void stop()
          已过时。 此方法具有固有的不安全性。有关详细信息,请参阅 Thread.stop()
 void suspend()
          已过时。 此方法容易导致死锁。有关详细信息,请参阅 Thread.suspend()
 String toString()
          返回此线程组的字符串表示形式。
 void uncaughtException(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错误输出流,并结束该线程。

看下面的例子:

  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

Java多线程 5 多线程其他知识简要介绍的更多相关文章

  1. java 多线程 start方法 run方法 简单介绍。

    一 start开启一个多线程, run 只是一个内部的方法. package com.aaa.threaddemo; /* * start方法的作用? * 在 Java中启动多线程调用的是start方 ...

  2. Java并发和多线程:序

      近期,和不少公司的"大牛"聊了聊,当中非常多是关于"并发和多线程"."系统架构"."分布式"等方面内容的.不少问题, ...

  3. Java面试专题-多线程篇(2)- 锁和线程池

  4. Java面试专题-多线程(3)-原子操作

  5. Java Hour 14 多线程基础

    有句名言,叫做10000小时成为某一个领域的专家.姑且不辩论这句话是否正确,让我们到达10000小时的时候再回头来看吧. 本文作者Java 现经验约为13 Hour,请各位不吝赐教. 多线程 这个是基 ...

  6. Java线程与多线程教程

    本文由 ImportNew - liken 翻译自 Journaldev.   Java线程是执行某些任务的轻量级进程.Java通过Thread类提供多线程支持,应用可以创建并发执行的多个线程. 应用 ...

  7. Java多线程(一) 多线程的基本使用

    在总结JDBC数据库连接池的时候,发现Java多线程这块掌握得不是很好,因此回头看了下多线程的内容.做一下多线程模块的学习和总结,稳固一下多线程这块的基础.关于多线程的一些理论知识,这里不想啰嗦太多, ...

  8. Java面试题-多线程

    1. java中有几种方法可以实现一个线程? 多线程有两种实现方法,分别是继承Thread类与实现Runnable接口. 这两种方法的区别是,如果你的类已经继承了其它的类,那么你只能选择实现Runna ...

  9. {python--GIL锁}一 介绍 二 GIL介绍 三 GIL与Lock 四 GIL与多线程 五 多线程性能测试

    python--GIL锁 GIL锁 本节目录 一 介绍 二 GIL介绍 三 GIL与Lock 四 GIL与多线程 五 多线程性能测试 一 背景知识 ''' 定义: In CPython, the gl ...

随机推荐

  1. 7个高性能JavaScript代码高亮插件

    本文由码农网 – 小峰原创,转载请看清文末的转载要求,欢迎参与我们的付费投稿计划! 对于喜欢写技术博客的同学来说,一定对代码高亮组件非常熟悉.一款优秀的JavaScript代码高亮插件,将会帮助你渲染 ...

  2. error at ::0 can't find referenced pointcut messageInsertAspect

    解决方法: http://stackoverflow.com/questions/10482563/aop-java-lang-illegalargumentexception-error-at-0- ...

  3. iOS 浅复制和深复制的深层理解,含示例

    转载:https://www.zybuluo.com/MicroCai/note/50592 版权归 @MicroCai 所有 以下是正文: 浅复制就是指针拷贝:深复制就是内容拷贝. 集合的浅复制 ( ...

  4. tomcat安装后,本地可以访问,远程不能访问

    问题描述:tomcat安装后,在本地可以使用本地IP地址.localhost可以访问,但是在远程却不能访问. 使用工具:无. 解决方法:关闭服务器端的"公用网络防火墙"即可.

  5. android onNewIntent调用时机

    (转自:http://www.cnblogs.com/zenfly/archive/2012/02/10/2345196.html) 在IntentActivity中重写下列方法:onCreate o ...

  6. 利用联合双边滤波或引导滤波进行升采样(Upsampling)技术提高一些耗时算法的速度。

    这十年来,在图像处理领域提出了很多新的图像分析和处理方法,包括是自动的以及一些需要有人工参与的,典型的比如stereo depth computations.image colorization.to ...

  7. HDU 1564 Play a game(巴什博弈)

    New Year is Coming! ailyanlu is very happy today! and he is playing a chessboard game with 8600. The ...

  8. Linux下的串口编程及非阻塞模式

    本篇介绍了如何在linux系统下向串口发送数据.包括read的阻塞和非阻塞.以及select方法. 打开串口 在Linux系统下,打开串口是通过使用标准的文件打开函数操作的. #include < ...

  9. nodejs中异常错误的处理方式

    因为nodejs是单线程的,所以一旦发生错误或异常,如果没有及时被处理整个系统就会崩溃.错误异常有两种场景的出现,一种是代码运行中throw new error没有被捕获,另一种是Promise的失败 ...

  10. 配置VSCode右键菜单

    修改注册表,添加鼠标右键 选择文件 Windows Registry Editor Version 5.00 [HKEY_CLASSES_ROOT\*\shell\VSCode]@="Ope ...