news 2026/4/15 16:31:54

深入浅出线程组和线程优先级

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
深入浅出线程组和线程优先级
今天我们来简单的介绍一下线程组和线程的关系,以及线程优先级的相关内容。

线程组(ThreadGroup)

Java 用 ThreadGroup 来表示线程组,我们可以通过线程组对线程进行批量控制。
每个 Thread 必然存在于一个 ThreadGroup 中,Thread 不能独立于 ThreadGroup 存在。执行main()方法的线程名字是 main,如果在 new Thread 时没有显式指定,那么默认将父线程(当前执行 new Thread 的线程)线程组设置为自己的线程组。
示例代码:
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());
以下是程序的运行结果:
ThreadGroup 是一个标准的向下引用的树状结构,这样设计可以防止"上级"线程被"下级"线程引用而无法有效地被 GC 回收

线程组的常用方法及数据结构

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

Thread.currentThread().getThreadGroup().getName()

复制线程组

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

线程组统一异常处理

// 创建一个线程组,并重新定义异常 ThreadGroup group = new ThreadGroup("testGroup") { @Override public void uncaughtException(Thread t, Throwable e) { System.out.println(t.getName() + ": " + e.getMessage()); } }; // 测试异常 Thread thread = new Thread(group, () -> { // 抛出 unchecked 异常 throw new RuntimeException("测试异常"); }); // 启动线程 thread.start();

线程的优先级

线程优先级可以指定,范围是 1~10。但并不是所有的操作系统都支持 10 级优先级的划分(比如有些操作系统只支持 3 级划分:低、中、高),Java 只是给操作系统一个优先级的参考值,线程最终在操作系统中的优先级还是由操作系统决定。
Java 默认的线程优先级为 5,线程的执行顺序由调度程序来决定,线程的优先级会在线程被调用之前设定。
通常情况下,高优先级的线程将会比低优先级的线程有更高的概率得到执行。Thread类的setPriority()方法可以用来设定线程的优先级。
Thread t1 = new Thread(); System.out.println("线程默认优先级:" + t1.getPriority()); Thread t2 = new Thread(); t2.setPriority(10); System.out.println("线程设置优先级等级为10后,线程的优先级:" + t2.getPriority());
输出结果:
既然有 10 个级别来设定线程的优先级,那是不是可以在业务实现的时候,采用这种方法来指定线程执行的先后顺序呢?
对于这个问题,答案是:No!
Java 中的优先级不是特别的可靠,Java 程序中对线程所设置的优先级只是给操作系统一个建议,操作系统不一定会采纳。而真正的调用顺序,是由操作系统的线程调度算法来决定的
我们通过代码来验证一下:
public class MyThread extends Thread { @Override public 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++) { MyThread thread = new MyThread(); thread.setName("线程" + i); thread.setPriority(i); thread.start(); } } }
运行该程序,有时候可以按照优先级执行,有时却不行:
Java 提供了一个线程调度器来监视和控制处于RUNNABLE 状态的线程。
  • 线程的调度策略采用抢占式的方式,优先级高的线程会比优先级低的线程有更大的几率优先执行。
  • 在优先级相同的情况下,会按照“先到先得”的原则执行。
  • 每个 Java 程序都有一个默认的主线程,就是通过 JVM 启动的第一个线程——main 线程。
还有一种特殊的线程,叫做守护线程(Daemon),守护线程默认的优先级比较低。
  • 如果某线程是守护线程,那如果所有的非守护线程都结束了,这个守护线程也会自动结束。
  • 当所有的非守护线程结束时,守护线程会自动关闭,这就免去了还要继续关闭子线程的麻烦。
  • 线程默认是非守护线程,可以通过 Thread 类的 setDaemon 方法来设置为守护线程。

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

之前我们谈到一个线程必然存在于一个线程组中,那么当线程和线程组的优先级不一致的时候会怎样呢?我们来验证一下:
// 创建一个线程组 ThreadGroup threadGroup = new ThreadGroup("testGroup"); threadGroup.setMaxPriority(8); System.out.println("线程组的优先级:" + threadGroup.getMaxPriority()); // 创建一个线程属于上述线程组 Thread thread = new Thread(threadGroup,"testThread"); thread.setPriority(10); System.out.println("线程的优先级:" + thread.getPriority());
运行程序后的输出结果:
所以,如果某个线程的优先级大于线程所在线程组的最大优先级,那么该线程的优先级将会失效,取而代之的是线程组的最大优先级。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/14 0:44:37

普通人成为一名网络安全工程师难吗?

如果对该专业感兴趣且愿意为之努力&#xff0c;那么学起来是十分轻松的&#xff1b;如果不感兴趣且不愿下功夫&#xff0c;学习起来肯定比较难的 需要学什么&#xff1f; 成为网络安全工程师&#xff0c;需要经历3各阶段&#xff1a;初级安全工程师→中级安全工程师→高级安全…

作者头像 李华
网站建设 2026/4/13 17:26:48

教育行业,JAVA如何编写网页大文件上传的示例教程?

《大文件传输系统开发手记&#xff1a;一个老程序员的求生指南》 一、项目背景 最近接了个"地狱级"外包&#xff1a;客户要我用原生JS实现20G文件夹上传/下载&#xff0c;还要兼容IE9&#xff01;我摸着所剩无几的头发&#xff0c;看着100元预算&#xff0c;陷入了沉…

作者头像 李华
网站建设 2026/4/12 10:17:04

汽车制造行业,JAVA如何实现设计图纸的大文件上传示例?

作为国内专注于设计制造领域的软件厂商&#xff0c;近期我们正积极投身于大文件上传下载组件的调研工作。在当前业务场景下&#xff0c;我们有着明确且极具挑战性的需求&#xff1a;所选取的组件必须能够支持高达 100G 文件以及文件夹的上传下载功能&#xff0c;同时要全面适配…

作者头像 李华