2

线程的四个属性 - Java知者

 11 months ago
source link: https://www.cnblogs.com/javazhizhe/p/17453738.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

线程的四个属性

线程各属性纵览

如上图所示,线程有四个属性:

  • 线程优先级

1. 线程ID

  • 每个线程都有id,这个id不能修改

  • 线程id会不停的自增,从1开始

  • main函数就是第一个线程,id=1

id 是操作系统用来识别各个线程的编号,具有唯一性,从下面 java 的源码中看到,这个线程的Id初始值是0,但是每一次生成Id的时候都是先自增的(++threadSeqNumber),所以起始值实际是1。

1220983-20230603114109132-526428627.png

测试代码:

/******
 * 线程Id从1开始,JVM运行起来后,自己创建的线程的Id早已不是0
 */
public class Id {
    public static void main(String[] args) {
        Thread thread = new Thread();
        System.out.println("主线程Id:"+Thread.currentThread().getId());
        System.out.println("子线程Id:"+thread.getId());
    }
}

打印结果:

1220983-20230603114108892-1569212052.png

以上看到主线程的id为1,可以理解,那么为什么我们创建的子线程id就直接为12了???

我们打断点调试发现,在我们的子线程创建之前,JVM其实已经为我们创建了许多线程

1220983-20230603114108983-1543643478.png
  • Signal Dispatcher是把操作系统的信号发给我们适当的程序的。
  • Reference Handler是和GC相关的引用线程。
  • Finalizer是负责执行Finalizer对象的方法。

2. 线程名字

(1) 默认线程名的源码分析

  • 有参构造器,指定线程名
1220983-20230603114108920-1242804879.png
  • 无参构造器,默认为Thread- ,后接 nextThreadNum ,这个数字为0开始,自增
1220983-20230603114108953-1658179676.png
1220983-20230603114108891-593207344.png

(2) 手动设置线程名字 setName()

1220983-20230603114109109-614001558.png

从上图中 java 的源码可以看到,this.name = name 是修改 java 层面的线程的名字,然后 setNativeName() 是native方法(C/C++层面给线程的名字做一个设置),但当线程启动之后,这个C/C++层面的名字不能修改了;不过 Java 层面的线程名字还是可以修改的。为什么当线程起来之后C/C++层面不能修改,是因为他做了一个!=0(线程的状态)的判断,为0时就是线程 new 出来后还没有 start。

3. 守护线程

线程类型有两种:守护线程、用户线程

守护线程的作用: 给用户线程提供服务。

用户线程和守护线程分类的标准:这个线程是否会阻止 JVM 的退出。当还有用户线程在执行的时候JVM是不会停止的,如果当前只剩下了守护线程,那么守护线程会随着JVM一起停止。

线程类型的特性:

  • 线程类型默认继承自父线程
  • 通常而言,所有的守护线程都是由 JVM 启动。在 JVM 启动的时候有一个非守护线程,那就是main函数。
  • 守护线程不影响 JVM退出,当 JVM 退出的时候,他只看有没有用户线程。

守护线程和用户线程区别

  • 整体上没有区别(只是代码的任务不一样)
  • 唯一区别在于是否影响 JVM 的退出(如果是用户线程会影响JVM的退出,守护线程则不会)

4. 线程优先级

Q:线程的优先级是什么?

A:在操作系统中,线程可以划分优先级,线程优先级越高,获得 CPU 时间片的概率就越大,但线程优先级的高低与线程的执行顺序并没有必然联系,优先级低的线程也有可能比优先级高的线程先执行。

优先级有10个级别,默认5,在Java源码中有三个定义,最低,默认,最高的优先级定义,如下图。

1220983-20230603114108924-961112158.png

线程虽然有优先级这个设定,但是实际开发中尽量不要设置优先级,即对程序的设计不应该依赖于优先级,主要原因如下:

  • 不同的操作系统优先级不同

    • window中只有7个优先级,java 程序运行在 windows 系统时,会进行优先级映射时,就可能会有多个优先级映射成一个优先级

    • linux中所有线程优先级会被忽略,所有线程优先级一致

  • 优先级可能会被操作系统修改,即优先级高的程序不一定被优先执行

属性总结

文章来源:https://mp.weixin.qq.com/s?__biz=MzU3NDgyMTIxMw==&mid=2247484552&idx=2&sn=9667c58b85d0cc52a30d27beec36087d&chksm=fd2dc2baca5a4bac168dccfd70d55e39db7203b0ef60a53e2e0ff9fd3f8bba7b9558e7d322f7#rd

个人微信:CaiBaoDeCai

微信公众号名称:Java知者

微信公众号 ID: JavaZhiZhe

谢谢关注!


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK