ThreadGroup thread group

 

1 Thread Group Concept

Java provides thread group classes: java.lang.ThreadGroup, ThreadGroup thread group is to facilitate the management of threads, it can uniformly set the priority of the threads in the thread group, or set it as a daemon thread, or set an exception handler for no exception handler. The thread sets a unified exception handler, etc., and at the same time, some information about the threads in the thread group can be easily obtained through the thread group.

 

By looking at the construction method of the Thread thread class, you can find that when instantiating a thread object, you can specify the thread group to which it belongs, Thread(ThreadGroup group,...). If a thread group is not specified when a thread is created, the thread will automatically belong to the group of the thread that created the thread by default. For example, a thread created in the main method, if no thread group is specified, it will belong to the main thread. Thread group (main thread group). Once a thread belongs to a thread group, the thread group it belongs to cannot be changed. And only when the start() method is called to start the thread, the thread is actually added to the thread group.

 

Each thread group ThreadGroup can contain a group of threads and a group of thread groups, so the thread group exists in the form of a tree. Usually, the top root thread group is the system thread group, and the system thread group is the main thread group. , so if the thread created in the main method does not specify the thread group, then it will belong to the main thread group, if the thread group is specified (and the parent thread group is not set), then its parent thread group will be the main thread group.

 

2 Thread Group API (Partial....)

ThreadGroup(String name), constructor 1, the parent thread group will be the thread group to which the thread that created the thread belongs by default. 

ThreadGroup(ThreadGroup parent, String name) Constructor 2, specifies the parent thread group.

 

int activeCount() Returns the estimated number of active threads in this thread group. Notice. By default, its child thread groups also do calculations.

int activeGroupCount() Returns the estimated number of active child thread groups in this thread group.

 

void checkAccess() Determines whether the currently running thread has permission to modify this thread group. Throws a SecurityException if the calling thread does not have permission to modify the thread group.

 

void destroy() Destroys this thread group and all its subgroups.

void interrupt() Interrupts all threads in this thread group.

 

int enumerate(Thread[] list) Copies all active threads in this thread group and its subgroups into the specified array list.

int enumerate(Thread[] list, boolean recurse) Copies all active threads in this thread group into the specified array. If recurse is true, the active threads in the child thread group are also copied together, that is, int enumerate(Thread[] list).

 

int enumerate(ThreadGroup[] list) Copies references to all active thread groups and their child thread groups in this thread group into the specified array.

int enumerate(ThreadGroup[] list, boolean recurse) 如果recurse为true,同enumerate(ThreadGroup[] list)。

 

void setDaemon(boolean daemon) Changes the daemon state for this thread group.

 

void setMaxPriority(int pri) Sets the highest priority of the thread group.

 

void uncaughtException(Thread t, Throwable e) This method is called by the JVM when a thread in this thread group stops due to an uncaught exception and the thread itself has not specified a specific Thread.UncaughtExceptionHandler.

 

 

public void uncaughtException(Thread t, Throwable e) {
        if (parent != null) {
            parent.uncaughtException(t, e);
        } else {
            Thread.UncaughtExceptionHandler ueh =
                Thread.getDefaultUncaughtExceptionHandler();
            if (ueh != null) {
                ueh.uncaughtException(t, e);
            } else if (!(e instanceof ThreadDeath)) {
                System.err.print("Exception in thread \""
                                 + t.getName() + "\" ");
                e.printStackTrace(System.err);
            }
        }
    }
 

 

线程组中的线程出现运行时异常会首先调用线程自己的异常处理器(Thread线程类也有setUncaughtExceptionHandler方法可以设置异常处理器),如果线程自身没有定义则会调用线程组的异常处理器,即默认情况下允许上面的代码:

如果父线程组存在, 则调用它的uncaughtException方法.

如果父线程组不存在, 但指定了默认处理器Thread.getDefaultUncaughtExceptionHandler, 则调用默认的处理器。

如果默认处理器没有设置, 则写错误日志.但如果 exception是ThreadDeath实例的话,则忽略。

 

3 线程组结论

线程组存储了线程对象和关联的线程组对象,并可以访问它们的信息(例如状态),将执行操作应用到所有成员上(例如中断)。

 

线程组和线程池的区别

线程组和线程池是两个不同的概念,他们的作用完全不同,前者是为了方便线程的管理,后者是为了管理线程的生命周期,复用线程,减少创建销毁线程的开销。

 

后记

java程序启动至少会启动几个线程?

一、利用ThreadGroup获得结果

public class ThreadDemo {
  public static void main(String[] args) {
    ThreadGroup g = Thread.currentThread().getThreadGroup();
    while (g != null) {
      ThreadGroup temp = g.getParent();
      if (temp == null) {
        break;
      }
      g = temp;
    }

    // 现在g就是根线程组
    System.out.println("active count is " + g.activeCount());

    Thread[] all = new Thread[g.activeCount()];
    g.enumerate(all);
    for (Thread t : all) {
      System.out.println(t.getName());
    }
  }
}

 

二、利用ThreadMXBean获得结果

public class ThreadNumDemo {
    public static void main(String[] args) {
        ThreadMXBean threadMXBean =ManagementFactory.getThreadMXBean();
        ThreadInfo[] threadInfos=threadMXBean.dumpAllThreads(false,false);
        for (ThreadInfo threadInfo : threadInfos) {
            System.out.println(threadInfo.getThreadId()+"-"+threadInfo.getThreadName());
        }
    }
}

 

以上两种方式获得结果应该是一致的,如果JDK版本一致的话。不同的JDK版本得出的结果可能是不同的。在JDK1.7上的结果为5个:

1. Reference Handler     //清除reference的线程

2. Finalizer                     //调用对象的finalize方法的线程,就是垃圾回收的线程

3. Signal Dispatcher      //分发处理发送给JVM信号的线程

4. Attach Listener         

5. main                          //主线程

 

这5个线程除了main是我们自己代码run所在的线程,其他都是虚拟机启动的线程。

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326505467&siteId=291194637