老师你好,想问一个关于线程修改名字的问题,setName 方法中的 setNativeName 方法的执行条件的问题

来源:1-2 为何我们需要每一个你

但为君故乚

2020-09-27

老师你好,我最近在学习关于线程的知识时,对于网上搜索到的文章资料,线程修改名字这里的 setNativeName 方法的执行条件感到有些困惑。因为网上收集的资料大都是一样的说这个方法线程启动之后不能执行了。

这是我在网上收集到的资料:
在这里插入图片描述
在这里插入图片描述

对于这些描述,我感到有些困惑,网上的文章资料说由于有一个检查线程状态不是 0 的判断,所以线程启动后不能对 C/C++ 层面的名字进行修改。但是对于这个线程状态,源码中的注释的意思不是说初始化时表示线程未启动,也就是值为 0 的时候:

/* Java thread status for tools,
 * initialized to indicate thread 'not yet started'
 */
private volatile int threadStatus = 0;

那么这个不等于 0 的判断是否可以理解为处于初始化状态时,也就是未启动时不能执行这个 setNativeName 方法,而启动后是可以执行的?

不知道我的理解有没有错误,又或者是网上的文章描述有些许错误,希望老师可以指教一下。

写回答

1回答

张勤一

2020-09-27

同学你好:

    其实这个问题深入研究的价值不大,只需要知道这个方法可以设置线程的名称即可。我这里简单说下 Thread 源码 setName 的逻辑吧。

    可以从 java 的源码看出,线程的默认名字是一个写死的“Thread-”加一个数字,这个数字是自增的,且加了 synchronized 不会出现重复的情况。

public Thread() {
    init(null, null, "Thread-" + nextThreadNum(), 0);
}

private static int threadInitNumber;
private static synchronized int nextThreadNum() {
    return threadInitNumber++;
}

    Thread 允许我们使用 setName 方法手动设置线程的名字。从 java 的源码中可以看到,首先是一个健康检查,然后底下的 setNativeName() 是 native 方法(C/C++ 层面给线程的名字做一个设置),也就是当线程启动之后,这个名字是不能修改了;但是 Java 内部的线程名字是可以通过 setName() 的方式来进行修改名字的。为什么当线程起来之后不能修改,是因为他做了一个 !=0(线程的状态)的判断,为 0 时就是线程还没有启动的时候。

public final synchronized void setName(String name) {
    checkAccess();
    if (name == null) {
        throw new NullPointerException("name cannot be null");
    }

    this.name = name;
    if (threadStatus != 0) {
        setNativeName(name);
    }
}

    

    我是勤一,致力于将这门课程的问答区打造为 Java 知识体系知识库,Java 知识体系 BBS!共同建造、维护这门课程,我需要每一个你!

2
1
但为君故乚
感谢老师的回答?
2020-09-27
共1条回复

Java实操避坑指南 SpringBoot/MySQL/Redis错误详解

掌握业务开发中各种类型的坑,,Java web开发领域通用

452 学习 · 204 问题

查看课程