1 线程组概念
Java中提供了线程组类: java.lang.ThreadGroup, ThreadGroup线程组是为了方便管理线程,它可以统一设定线程组中的线程的优先级,或者设置为守护线程,或者为没有设置异常处理器的线程设置统一的异常处理器等等,同时也可以通过线程组方便的获的线程组中的线程的一些信息。
通过查看Thread线程类的构造方法,可以发现在实例化线程对象的时候,可以指定所属的线程组,Thread(ThreadGroup group,...)。如果创建线程的时候没有指定线程组,那么该线程将会默认自动属于创建该线程的线程所在的组,例如在main方法中创建的线程,如果没有指定线程组,那么将会属于main线程所在的线程组(main线程组)。一旦一个线程归属到一个线程组之中后,就不能再更换其所在的线程组。并且只有当调用start()方法启动线程的时候,才真正的把线程加入到了线程组中。
每个线程组ThreadGroup 又可以包含一组线程和一组线程组,所以线程组是以树状形式存在,通常情况下,最顶层的根线程组是system线程组,system线程组下是main线程组,所以在main方法中创建的线程如果没有指定线程组,那么它将属于main线程组,如果指定了线程组(并且没有设置父线程组),那么它的父线程组将会是main线程组。
2 线程组API(部分....)
ThreadGroup(String name),构造方法1,父线程组将会默认是创建该线程的线程所属的线程组。
ThreadGroup(ThreadGroup parent, String name) 构造方法2,指定了父线程组。
int activeCount() 返回此线程组中活动线程的估计数。 注意。默认情况 下,其子线程组也会进行计算。
int activeGroupCount() 返回此线程组中活动子线程组的估计数。
void checkAccess() 确定当前运行的线程是否有权修改此线程组。 如果调用线程没有权限修改线程组抛出SecurityException。
void destroy() 销毁此线程组及其所有子组。
void interrupt() 中断此线程组中的所有线程。
int enumerate(Thread[] list) 把此线程组及其子组中的所有活动线程复制到指定数组list中。
int enumerate(Thread[] list, boolean recurse) 把此线程组中的所有活动线程复制到指定数组中。 如果recurse为true,则还要将子线程组中的活动线程一起复制 即int enumerate(Thread[] list)。
int enumerate(ThreadGroup[] list) 把此线程组中的所有活动线程组及其子线程组的引用复制到指定数组中。
int enumerate(ThreadGroup[] list, boolean recurse) 如果recurse为true,同enumerate(ThreadGroup[] list)。
void setDaemon(boolean daemon) 更改此线程组的后台程序状态。
void setMaxPriority(int pri) 设置线程组的最高优先级。
void uncaughtException(Thread t, Throwable e) 当此线程组中的线程因为一个未捕获的异常而停止,并且线程自身没有指定特定 Thread.UncaughtExceptionHandler 时,由JVM调用此方法。
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所在的线程,其他都是虚拟机启动的线程。
相关推荐
1、从源码解析ThreadGroup,介绍ThreadGroup父子关系 2、简介jdk的CAS 3、线程池内部默认的线程工厂和拒绝策略的形式
多线程复习,欢迎大家Star 包名和内容对应如下: no1_thread_imply 线程的几种实现...no10_threadgroup 线程组 no11_thread_catch_exception 指定异常捕获类捕获线程中的异常 no12_producter_consumer_wait_no
线程组:ThreadGroup, 一个线程组可以有多个线程,也可以有很多子线程组 二、线程池:系统每产一个线程要占用较多时间,所以我们可以用线程池,在池中预放n个线程,用时取出,不用时可以还回去。
主要介绍了Java线程组操作,结合实例形式分析了ThreadGroup类创建与使用线程组相关操作技巧,需要的朋友可以参考下
主要介绍了Java并发编程示例(十):线程组,Java提供了ThreadGroup类来控制一个线程组,一个线程组可以通过线程对象来创建,也可以由其他线程组来创建,生成一个树形结构的线程,需要的朋友可以参考下
本书第二版提供了对Thread和ThreadGroup类、Runnable接口和语言的同步操作符内容的全面讨论。它解释了如何在不同的平台上调度线程,如何开发CPUScheduler类来实现你自己的调度策略。其他扩展例子包括实现读/写锁、...
多线程基本概念 创建线程的方式 线程的生命周期及控制 线程的优先级及调度 多线程的互斥与同步 守护线程 (Daemon) 线程组 (ThreadGroup)
jmeter插件相关引用请参阅:jmeter插件推荐 自定义线程组:jp@gc - Ultimate Thread Group 此线程组功能强大,可以实现多种场景设置,添加路径如图
– group 线程组 – target 执行方法 – name 线程名字 – args target执行的元组参数 – kwargs target执行的字典参数 Thread对象函数 函数 描述 start() 开始线程的执行 run() 定义线程的功能的函数(一般会...
ThreadGroup是基于线程并发的编程语言中常用的一个概念,当一个线程派生出一个子线程后通常会加入父线程的线程组(未指定线程组的情况下)中, 最后可以通过ThreadGroup来控制一组线程的退出等操作, 然后在go语言中...
目录 线程的启动和终止 1、线程的构造 1.1继承Thread类 1.2实现Runnable接口 2、启动线程 3、线程的中断 3.1运行态的中断/阻塞态中断 ...ThreadGroup g:线程组 Runnable target:可以调用run方法的对象 String
Jmeter 的组件包括测试计划、线程组、setup thread group、teardown thread group、sample、逻辑控制器、定时器、前置处理器、后置处理器、断言和监听器等。其中,测试计划是根节点,所有的内容都是基于这个计划下的...
但现在线程没有优先级,没有线程组,不能被销毁、停止、暂停、开始和打断。 Java Thread类的静态方法,被移植成了模块方法。 main thread: 运行python程序的线程 daemon thread 守护线程,如果守护线程之外的线程都...
并行作业-异步进程-线程 ... 在这里,我可以解释我如何在* NIX OS上完成此必不可少的功能。 ...这样,您的代码就可以实现这一目标。...分派单个线程(默认组) 它使用一个参数“ single_command_default_g
目前的FTP软件都是多线程的,每一个客户连接都会建立一个新的线程,而每个进程[即程序]最多大概能建立2000-4000个线程,也就是说同时最多能有2000-4000个人在线,当然要建立到那么多线程,我们家用电脑如何行通呢?...
马尔 Marl是用C ++ 11编写的混合线程/光纤任务调度程序。 关于 Marl是一个C ++ 11库,它提供了一个流畅的界面,可用于跨多个线程运行任务。...# include " marl/waitgroup.h " # include < cstdio
该命令将返回归档日志文件的信息,包括日志文件的名称、时间戳、线程号、序列号等信息。 7. 增加与删除日志文件组: 使用以下命令可以增加日志文件组: ALTER DATABASE ADD LOGFILE GROUP 1 ('/home1/oracle/...
sleep是线程类(Thread)的方法,导致此线程暂停执行指定时间,给执行机会给其他线程,但是监控状态依然保持,到时后会自动恢复。调用sleep不会释放对象锁。 wait是Object类的方法,对此对象调用wait方法导致本线程...
多线程方法有助于模拟同时运行的电梯。 该模拟还利用了几种组调度算法,这些算法有助于在电梯轿厢之间分配工作量,并使电梯适应各种情况(例如,早上有更多的人-Up-Peak,每个人都将主要地板-分区)。 怎么跑 > cd ...
Win32_Thread,//系统线程 Win32_Share,//共享 Win32_NetworkClient,//已安装的网络客户端 Win32_NetworkProtocol,//已安装的网络协议 主要方法定义: // 获取Windows的“设备”名称的DataTable public static ...