欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 教育 > 锐评 > Java 线程组与线程优先级详解

Java 线程组与线程优先级详解

2026/5/2 2:12:58 来源:https://blog.csdn.net/gaosw0521/article/details/143889600  浏览:    关键词:Java 线程组与线程优先级详解

1 引言

在 Java 多线程编程中,线程组(ThreadGroup)和线程优先级是两个重要的概念。线程组用于管理一组相关的线程,而线程优先级则影响操作系统为线程分配处理器时间的顺序。本文将详细介绍线程组和线程优先级的使用方法及其背后的原理。

2 线程组(ThreadGroup)

Java 提供了 ThreadGroup 类来表示线程组,我们可以通过线程组对线程进行批量控制。每个 Thread 必然存在于一个 ThreadGroup 中,Thread 不能独立于 ThreadGroup 存在。执行 main() 方法的线程名字是 main,如果在 new Thread 时没有显式指定,那么默认将父线程(当前执行 new Thread 的线程)线程组设置为自己的线程组。

2.1 示例代码

Thread testThread = new Thread(() -> {System.out.println("testThread当前线程组名字:" +Thread.currentThread().getThreadGroup().getName());System.out.println("testThread线程名字:" +Thread.currentThread().getName());
});testThread.start();
System.out.println("执行main所在线程的线程组名字: " + Thread.currentThread().getThreadGroup().getName());
System.out.println("执行main方法线程名字:" + Thread.currentThread().getName());

输出结果:

执行main所在线程的线程组名字: main
testThread当前线程组名字:main
testThread线程名字:Thread-0
执行main方法线程名字:main

ThreadGroup 是一个标准的向下引用的树状结构,这样设计可以防止“上级”线程被“下级”线程引用而无法有效地被 GC 回收。

2.2 线程组的常用方法

  • 获取当前线程的线程组名字

    Thread.currentThread().getThreadGroup().getName()
    
  • 复制线程组

    // 获取当前的线程组
    ThreadGroup threadGroup = Thread.currentThread().getThreadGroup();
    // 复制一个线程组到一个线程数组(获取Thread信息)
    Thread[] threads = new Thread[threadGroup.activeCount()];
    threadGroup.enumerate(threads);
    
  • 线程组统一异常处理

    ThreadGroup group = new ThreadGroup("testGroup") {@Overridepublic void uncaughtException(Thread t, Throwable e) {System.out.println(t.getName() + ": " + e.getMessage());}
    };Thread thread = new Thread(group, () -> {throw new RuntimeException("测试异常");
    });thread.start();
    

2.3 线程组的数据结构

ThreadGroup 类中的成员变量:

public class ThreadGroup implements Thread.UncaughtExceptionHandler {private final ThreadGroup parent; // 父亲ThreadGroupString 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() {this.name = "system";this.maxPriority = Thread.MAX_PRIORITY;this.parent = null;
}// 默认是以当前ThreadGroup作为parent ThreadGroup,新线程组的父线程组是目前正在运行线程的线程组。
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);
}

checkParentAccess 方法:

private static Void checkParentAccess(ThreadGroup parent) {parent.checkAccess();return null;
}public final void checkAccess() {SecurityManager security = System.getSecurityManager();if (security != null) {security.checkAccess(this);}
}

3 线程的优先级

线程优先级可以指定,范围是 1~10。但并不是所有的操作系统都支持 10 级优先级的划分(比如有些操作系统只支持 3 级划分:低、中、高),Java 只是给操作系统一个优先级的参考值,线程最终在操作系统中的优先级还是由操作系统决定。

Java 默认的线程优先级为 5,线程的执行顺序由调度程序来决定,线程的优先级会在线程被调用之前设定。通常情况下,高优先级的线程将会比低优先级的线程有更高的概率得到执行。Thread 类的 setPriority() 方法可以用来设定线程的优先级。

Thread a = new Thread();
System.out.println("我是默认线程优先级:" + a.getPriority());
Thread b = new Thread();
b.setPriority(10);
System.out.println("我是设置过的线程优先级:" + b.getPriority());

输出结果:

我是默认线程优先级:5
我是设置过的线程优先级:10

3.1 线程优先级的可靠性

Java 中的优先级不是特别的可靠,Java 程序中对线程所设置的优先级只是给操作系统一个建议,操作系统不一定会采纳。而真正的调用顺序,是由操作系统的线程调度算法来决定的。

static class MyThread extends Thread {@Overridepublic void run() {System.out.println("MyThread当前线程:" + Thread.currentThread().getName()+ ",优先级:" + Thread.currentThread().getPriority());}
}public static void main(String[] args) {for (int i = 1; i <= 10; i++) {Thread thread = new MyThread();thread.setName("线程" + i);thread.setPriority(i);thread.start();}
}

运行该程序,有时候可以按照优先级执行,有时却不行。

MyThread当前线程:线程3,优先级:3
MyThread当前线程:线程6,优先级:6
MyThread当前线程:线程5,优先级:5
MyThread当前线程:线程4,优先级:4
MyThread当前线程:线程2,优先级:2
MyThread当前线程:线程1,优先级:1
MyThread当前线程:线程8,优先级:8
MyThread当前线程:线程10,优先级:10
MyThread当前线程:线程7,优先级:7
MyThread当前线程:线程9,优先级:9

3.2 线程调度器

Java 提供了一个线程调度器来监视和控制处于 RUNNABLE 状态的线程。线程的调度策略采用抢占式的方式,优先级高的线程会比优先级低的线程有更大的几率优先执行。在优先级相同的情况下,会按照“先到先得”的原则执行。每个 Java 程序都有一个默认的主线程,就是通过 JVM 启动的第一个线程——main 线程。

3.3 守护线程(Daemon)

还有一种特殊的线程,叫做守护线程(Daemon),守护线程默认的优先级比较低。如果某线程是守护线程,那如果所有的非守护线程都结束了,这个守护线程也会自动结束。当所有的非守护线程结束时,守护线程会自动关闭,这就免去了还要继续关闭子线程的麻烦。线程默认是非守护线程,可以通过 Thread 类的 setDaemon 方法来设置为守护线程。

4 线程组和线程优先级之间的关系

如果某个线程的优先级大于线程所在线程组的最大优先级,那么该线程的优先级将会失效,取而代之的是线程组的最大优先级。

ThreadGroup group = new ThreadGroup("testGroup");
group.setMaxPriority(7);
Thread thread = new Thread(group, "test-thread");
thread.setPriority(10);
System.out.println("线程组的优先级是:" + group.getMaxPriority());
System.out.println("线程的优先级是:" + thread.getPriority());

输出:

线程组的优先级是:7
线程的优先级是:7

5 小结

Java 提供了 ThreadGroup 类来创建一组相关的线程,使线程组管理更方便;每个 Java 线程都有一个优先级,这个优先级会影响到操作系统为这个线程分配处理器时间的顺序。线程组和线程优先级的结合使用,可以帮助我们更好地管理和调度线程。

通过本文的学习,希望读者能够更好地掌握 Java 线程组和线程优先级的使用方法及其背后的原理,为后续深入学习 Java 并发编程打下坚实的基础。

6 思维导图

在这里插入图片描述

7 参考资料

线程组和线程优先级(冷门知识)

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词