首页 > 其他分享 >线程组和线程优先级

线程组和线程优先级

时间:2024-07-18 20:51:05浏览次数:11  
标签:组和 优先级 Thread parent ThreadGroup 线程 main

线程组


每个 Thread 必然存在于一个 ThreadGroup 中,Thread 不能独立于 ThreadGroup 存在。执行main()方法的线程名字是 main,如果在 new Thread 时没有显式指定,那么默认将父线程的线程组设置为自己的线程组。

public static void main(String[] args) {
    Thread thread = new Thread(() -> {
        // thread当前线程组名字:main
        System.out.println("thread当前线程组名字:" +
                Thread.currentThread().getThreadGroup().getName());
        // thread线程名字:Thread-0
        System.out.println("thread线程名字:" +
                Thread.currentThread().getName());
    });

    thread.start();
    // 执行main所在线程的线程组名字: main
    System.out.println("执行main所在线程的线程组名字: " + Thread.currentThread().getThreadGroup().getName());
    // 执行main方法线程名字:main
    System.out.println("执行main方法线程名字:" + Thread.currentThread().getName());
}

ThreadGroup 是一个标准的向下引用的树状结构,这样设计可以防止"上级"线程被"下级"线程引用而无法有效地被 GC 回收。每个线程组下面可以有多个线程或者线程组。线程组可以起到统一控制线程的优先级和检查线程权限的作用。

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

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

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

复制线程组

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

线程组统一异常处理

public static void main(String[] args) {
    // 创建一个线程组,并重新定义异常
    ThreadGroup group = new ThreadGroup("testGroup") {
        @Override
        public void uncaughtException(Thread t, Throwable e) {
            // Thread-0: 测试异常
            System.out.println(t.getName() + ": " + e.getMessage());
        }
    };

    // 测试异常
    Thread thread = new Thread(group, () -> {
        // 抛出 unchecked 异常
        throw new RuntimeException("测试异常");
    });

    // 启动线程
    thread.start();
}

线程组的数据结构

成员变量:

public class ThreadGroup implements Thread.UncaughtExceptionHandler {
    // 父亲ThreadGroup
    private final ThreadGroup parent; 
    // ThreadGroup 的名称
    String name; 
    // 最大优先级
    int maxPriority; 
    // 是否被销毁
    boolean destroyed; 
    // 是否守护线程
    boolean daemon; 
    // 是否可以中断
    boolean vmAllowSuspension; 
    // 还未启动的线程
    int nUnstartedThreads = 0; 
    // ThreadGroup中线程数目
    int nthreads; 
    // ThreadGroup中的线程
    Thread threads[]; 
	// 线程组数目
    int ngroups; 
    // 线程组数组
    ThreadGroup groups[]; 
}

构造方法:

// 私有构造方法
private ThreadGroup() {
    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);
}

checkParentAccess() 方法:

// 检查parent ThreadGroup
private static Void checkParentAccess(ThreadGroup parent) {
    parent.checkAccess();
    return null;
}

// 判断当前运行的线程是否具有修改线程组的权限
public final void checkAccess() {
    SecurityManager security = System.getSecurityManager();
    if (security != null) {
        security.checkAccess(this);
    }
}

SecurityManager 是 Java 的安全管理器,它允许应用程序在执行一个可能不安全或敏感的操作前确定该操作是什么,以及是否允许在执行该操作的上下文中执行它。

Thread 类也有一个 checkAccess 方法,不过是用来判断当前运行的线程是否有权限修改被调用的这个线程。

线程优先级


线程优先级可以指定,范围是 1~10(由低到高,默认是5)。Java 中的优先级不是特别的可靠,Java 程序中对线程所设置的优先级只是给操作系统一个建议,操作系统不一定会采纳。而真正的调用顺序,是由操作系统的线程调度算法来决定的。Thread类的setPriority()方法可以用来设定线程的优先级。

Java 提供了一个线程调度器来监视和控制处于RUNNABLE 状态的线程。

  • 线程的调度策略采用抢占式的方式,优先级高的线程会比优先级低的线程有更大的几率优先执行。
  • 在优先级相同的情况下,会按照“先到先得”的原则执行。
  • 每个 Java 程序都有一个默认的主线程,就是通过 JVM 启动的第一个线程——main 线程。

还有一种特殊的线程,叫做守护线程(Daemon),守护线程默认的优先级比较低。

  • 如果某线程是守护线程,那如果所有的非守护线程都结束了,这个守护线程也会自动结束。
  • 当所有的非守护线程结束时,守护线程会自动关闭,这就免去了还要继续关闭子线程的麻烦。
  • 线程默认是非守护线程,可以通过 Thread 类的 setDaemon 方法来设置为守护线程。

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


public static void main(String[] args) {
    // 创建一个线程组
    ThreadGroup group = new ThreadGroup("testGroup");
    // 将线程组的优先级指定为 7
    group.setMaxPriority(7);

    // 创建一个线程,将该线程加入到 group 中
    Thread thread = new Thread(group, "test-thread");
    // 企图将线程的优先级设定为 10
    thread.setPriority(10);
    
    // 输出线程组的优先级和线程的优先级,结果都是7
    System.out.println("线程组的优先级是:" + group.getMaxPriority());
    System.out.println("线程的优先级是:" + thread.getPriority());
}

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

标签:组和,优先级,Thread,parent,ThreadGroup,线程,main
From: https://www.cnblogs.com/sprinining/p/18310429

相关文章

  • 白骑士的C++教学实战项目篇 4.3 多线程网络服务器
    系列目录上一篇:白骑士的C++教学实战项目篇4.2学生成绩管理系统        在这一节中,我们将实现一个多线程网络服务器项目,通过该项目,我们将学习套接字编程的基础知识以及如何使用多线程处理并发连接。此外,我们还将实现一个简单的客户端来与服务器进行通信。项目简介......
  • 获取线程的执行结果
    无返回值的RunnablepublicinterfaceRunnable{publicabstractvoidrun();}publicstaticvoidmain(String[]args)throwsExecutionException,InterruptedException{//创建一个包含5个线程的线程池ExecutorServiceexecutorService=Executors.newF......
  • java map 是线程安全吗 map的线程安全实现类 推荐使用 ConcurrentHashMap
    javamap是线程安全吗map的线程安全实现类推荐使用ConcurrentHashMapHashMap线程安全的吗?Java中平时用的最多的Map集合就是HashMap了,它是线程不安全的。看下面两个场景:1、当用在方法内的局部变量时,局部变量属于当前线程级别的变量,其他线程访问不了,所以这时也不存在线程安全......
  • Java多线程入门
    创建线程的三种方式继承Thread类classMyThreadextendsThread{@Overridepublicvoidrun(){for(inti=0;i<100;i++){System.out.println(getName()+""+i);}}publicstaticvoidmain(String[]args......
  • 多线程三-线程安全之可见性与有序性
    volatile关键字来确保线程间的可见性,可以利用线程可见性在某些场景进行无锁化编程。下载Hotspot源码:官网:https://openjdk.org/左侧菜单,SourceCode下面的Mecurial点击jdk8点击hotspot点击zipvolatile关键字来确保线程间的可见性,可以利用线程可见性在某些场景进行无锁化......
  • @Transactional 中使用线程锁导致了锁失效
     当线程A将level设置为99时,此时锁已经释放了,但是事务还没提交!!线程B此时可以获取到锁并进行查询,查询出来的level还是线程A修改之前的100,所以出现了并发问题。 解决方案1、@Transactional单独一个方法privateLocklock=newReentrantLock();@Transactionalpublicvoid......
  • 线程池的执行流程
    线程池的执行流程是一个系统且有序的过程,它主要涉及到任务的提交、线程的分配、任务的执行以及线程的回收等多个环节。以下是对线程池执行流程的详细阐述:一、任务提交提交任务:当一个新的线程任务被提交到线程池时,线程池会首先尝试在线程池中分配一个空闲线程来执行这个任务。......
  • Java中的并发数据结构与多线程优化技术
    Java中的并发数据结构与多线程优化技术大家好,我是微赚淘客系统3.0的小编,是个冬天不穿秋裤,天冷也要风度的程序猿!在多线程编程中,并发数据结构和优化技术是提高系统性能和可靠性的关键。Java提供了丰富的并发数据结构和多线程优化技术,本文将详细介绍常用的并发数据结构及其使用方法......
  • java创建线程池的几中方式
    1.创建线程池四种方式使用Executors类,Executors类是Java中用于创建线程池的工厂类,它提供了多种静态方法来创建不同类型的线程池使用ThreadPoolExecutor类,ThreadPoolExecutor是Java中线程池的一个核心类,它提供了更细粒度的控制来创建和管理线程池使用Future和......
  • 能把进程和线程讲的这么透彻的,没有20年功夫还真不行【0基础也能看懂】
    本篇会加入个人的所谓鱼式疯言❤️❤️❤️鱼式疯言:❤️❤️❤️此疯言非彼疯言而是理解过并总结出来通俗易懂的大白话,小编会尽可能的在每个概念后插入鱼式疯言,帮助大家理解的.......