线程组的常用方法
1. 获取当前的线程组的名字
// 或者当前运行线程所属的线程组 Thread.currentThread().getThreadGroup().getName();
2. 复制线程组
// 复制一个线程数组到一个线程组 Thread[] threads = new Thread[2]; ThreadGroup threadGroup = new ThreadGroup("copyGroup"); threadGroup.enumerate(threads);
3. 线程组统一异常处理
public class ThreadGroupDemo{ public static void main(String[] args){ ThreadGroup threadGroup1 = new ThreadGroup("group1"){ // 继承ThreadGroup并重新定义一下方法 // 在【线程成员】抛出unchecked exception // 会执行次方法 @Override public void uncaughtException(Thread t, Throwable e) { super.uncaughtException(t, e); System.out.println(t.getName() + ": " + e.getMessage()); } }; // 这个线程是threadGroup1的一员 Thread thread1 = new Thread(threadGroup1, new Runnable(){ public void run(){ // 模拟抛出异常 throw new RuntimeException("测试异常"); } }); thread1.start(); } }
线程组的数据结构
线程组还可以包含其他的线程组,不仅仅是线程。
public class ThreadGroup implements Thread.UncaughtExceptionHandler {
private final ThreadGroup parent; // 父亲ThreadGroup
String name; // ThreadGroup的名称
int maxPriority; // 线程最大优先级
boolean destroyed; // 是否被销毁
boolean daemon; // 是否守护线程
boolean vmAllowSuspension; // 是否可以中断
int nUnstartedThreads = 0; // 还未启动的线程
int nthreads; // ThreadGroup中线程数目
Thread threads[]; // ThreadGroup中的线程
int ngroups; // 线程组数目
ThreadGroup groups[]; // 线程组数组
}
// 私有构造函数
private ThreadGroup() { // called from C code
this.name = "system";
this.maxPriority = Thread.MAX_PRIORITY;
this.parent = null;
}
public ThreadGroup(String name) {
//
this(Thread.currentThread().getThreadGroup(), name);
}
public ThreadGroup(ThreadGroup parent, String name) {
this(checkParentAccess(parent), parent, name);
}
// 私有构造函数,主要的构造函数
private ThreadGroup(Void unused, ThreadGroup parent, String name) {
this.name = name;
this.maxPriority = parent.maxPriority;
this.daemon = parent.daemon;
this.vmAllowSuspension = parent.vmAllowSuspension;
this.parent = parent;
parent.add(this);
}
// 检查parent
private static Void checkParentAccess(ThreadGroup parent) {
parent.checkAccess();
return null;
}
// 判断当前运行的线程是否具有修改线程组的权限
public final void checkAccess() {
// Java的安全管理器,它允许应用程序在执行一个可能不安全或敏感的操作前确定该操作时什么
// 以及是否是在允许执行该操作的安全上下文中执行它。
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkAccess(this);
}
}
总结来说,线程组是一个树状的结构,每个线程组下面可以有多个线程或者线程组。线程组可以起到统一控制线程优先级和检查线程权限的作用。
线程组与线程池的区别
线程组【线程组存在的意义,首先原因是安全】
Java默认创建的线程都是属于系统线程组,而同一个线程组的线程是可以相互修改彼此数据的,不同的线程组,不能“跨线程组”修改数据,可以保证数据安全。
线程池【效率】
线程的创建和结束都需要一定的系统时间,不停创建和删除线程会浪费大量的时间。所以,在创建一条线程并使其在执行完任务后不结束,而是使其进入休眠状态,在需要用时再唤醒,那么就可以节省一定的时间。如果使用线程池来进行管理,保证效率。
共同点:
- 管理一定数量的线程。
- 都可以对线程进行控制---包括休眠,唤醒,结束,创建,中断。