第2章 深入理解Thread构造函数

news2025/5/21 23:41:35

Thread的构造函数。
![[Pasted image 20241206152027.png]]

2.1 线程的命名


在构造一个Thread时可以为其命名。

2.1.1 线程的默认命名


下面构造函数中,并没有为线程命名。

Thread()
Thread(Runnable target)
Thread(ThreadGroup group, Runnable target)

打开源码会看到

public Thread(Runnable target) {  
    this(null, target, "Thread-" + nextThreadNum(), 0);  
}

private static int threadInitNumber;  

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

故对于没有命名的线程的名字会以"Thread-"开头,后面的数字依次递增。

public static void defaultName() {  
    Runnable runnable = () -> System.out.println(Thread.currentThread().getName());  
    // 将会创建三个线程并调用其start方法  
    IntStream.rangeClosed(1, 3).boxed().map(x -> runnable).map(Thread::new).forEach(Thread::start);  
}
输出 : 
Thread-1
Thread-0
Thread-2

2.1.2 命名线程


下面的构造方法可以在创建一个Thread时为其命名。

Thread(String name)
Thread(ThreadGroup group, Runnable target)
Thread(ThreadGroup group, Runnable target, String name)
Thread(ThreadGroup group, Runnable target, String name, long stackSize)
Thread(ThreadGroup group, Runnable target, String name, long stackSize,
boolean inheritThreadLocals)
Thread(ThreadGroup group, String name)
public static Runnable runnable = () -> System.out.println(Thread.currentThread().getName());  
public static List<String> list = Arrays.asList("anan", "jcjc", "yryr", "mymy");

public static void assignName() {  
    IntStream.rangeClosed(0, 3).boxed().map(list::get).map(threadName -> new Thread(runnable, threadName)).forEach(Thread::start);  
}
输出 : 
anan
jcjc
yryr
mymy

2.1.3 修改线程的名字


在线程启动之前,你可以更改线程的名字,但调用之后就不能更改了。
这是setName的源码

public final synchronized void setName(String name) {  
    checkAccess();  
    if (name == null) {  
        throw new NullPointerException("name cannot be null");  
    }  
    this.name = name;  
    if (threadStatus != 0) { // 线程不是NEW状态对其的修改不会生效  
        setNativeName(name);  
    }
}

2.2 线程的父子关系


  • 一个线程的创建肯定是由另一个线程完成的
  • 被创建的线程的父线程就是创建这个线程的线程。
例如在main线程中创建了一个线程x,那么x的父线程就是main线程

2.3 Thread与ThreadGroup


在线程的构造函数可以显式地指定线程的Group,也就是ThreadGroup
如果在构造一个线程时没有指定它的Group,那么会加入到父线程的Group

public static Runnable runnable2 = () -> System.out.println(Thread.currentThread().getThreadGroup().getName());
public static void defaultThreadGroup() {  
    // 创建一个线程  
    Thread thread = new Thread(runnable2, "mymy");  
    ThreadGroup group = new ThreadGroup("yjyj");  
    Thread thread1 = new Thread(group, runnable2, "jcjc");  
    thread.start();  
    thread1.start();  
}
输出 : 
main
yjyj

2.4 Thread和Runnable


Thread负责线程本身相关的职责和控制,而Runnable则负责逻辑执行单元的部分。

2.5 Thread与JVM虚拟机栈


。。。 这段太抽象了

2.5.1 Thread与Stacksize


2.5.2 JVM内存结构


JVM在执行Java程序的时候会把对应的物理内存划分成不同的内存区域,每一个区域都存放着不同数据,也有不同的创建与销毁时机,有些分区会在JVM启动时就创建,有些则是在运行时才创建。

![[Pasted image 20241206162347.png]]

  • 程序计数器
    程序计数器在JVM中所起的作用就是用于存放当前线程接下来将要执行的字节码指令、分支、循环、跳转、异常处理等信息。
  • Java虚拟机栈
    Java虚拟机栈也是线程私有的,它的生命周期与线程相同,是在JVM运行时所创建的,在线程中,方法在执行的时候都会创建一个名为栈帧(stack frame)的数据结构,主要用于存放局部变量表、操作栈、动态链接、方法出口等信息。
    ![[Pasted image 20241206162917.png]]

方法的调用是栈帧被压入和弹出的过程。同等的虚拟机栈如果局部变量表等占用内存
越小则可被压入的栈帧就会越多,反之则可被压入的栈帧就会越少,一般将栈帧内存的大小称为宽度,而栈帧的数量则称为虚拟机栈的深度。

  • 本地方法栈
    Java中提供了调用本地方法的接口(Java NativeInterface),也就是C/C++程序,在线程的执行过程
    中,经常会碰到调用JNI方法的情况,比如网络通信、文件操作的底层,甚至是String的intern等都是JNI方法,JVM为本地方法所划分的内存区域便是本地方法栈,这块内存区域其自由度非常高,完全靠不同的JVM厂商来实现,Java虚拟机规范并未给出强制的规定,同样它也是线程私有的内存区域。
  • 堆内存
    堆内存是JVM中最大的一块内存区域,被所有的线程所共享,Java在运行期间创建的所有对象几乎都存放在该内存区域,该内存区域也是垃圾回收器重点照顾的区域,因此有些时候堆内存被称为“GC堆”。
  • 方法区
    方法区也是被多个线程所共享的内存区域,他主要用于存储已经被虚拟机加载的类信息、常量、静态变量、即时编译器(JIT)编译后的代码等数据。

2.5.3 Thread与虚拟机栈


2.6 守护线程


守护线程是一类比较特殊的线程,一般用于处理一些后台的工作。

2.6.1 什么是守护线程


public static Runnable runnable3 = () -> {  
    while (true) {  
        System.out.println("haha");  
        sleep(1);  
    }  
};

public static void deamonThread() {  
    System.out.println(Thread.currentThread().getName());  
    Thread thread = new Thread(runnable3);  
    thread.setDaemon(true); // 将其设置为守护线程  
    thread.start(); // 启动线程  
}

main线程

deamonThread();  
sleep(1);
输出 : 
main
haha
haha

当main线程退出后,守护线程也随之自动关闭了。
如果父线程为守护线程那么子线程也为守护线程。

2.6.2 守护线程的作用


守护线程经常用作与执行一些后台任务,因此有时它也被称为后台线程,当你希望关闭某些线程的时候,或者退出JVM进程的时候,一些线程能够自动关闭,此时就可以考虑用守护线程为你完成这样的工作。

2.7 本章总结


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2302197.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

node 使用 Redis 缓存

缓存是什么&#xff1f; 高并发下&#xff0c;一个项目最先出问题的&#xff0c;并不是程序本身&#xff0c;而是数据库最先承受不住。 在数据库上我们可以做很多优化&#xff0c;例如优化 SQL 语句&#xff0c;优化索引&#xff0c;如果数据量大了&#xff0c;还可以分库、分表…

PMBOK第7版整体架构全面详解

1. 引言 7月1日对于项目管理从业者和研究者而言&#xff0c;是个非凡意义的一个时间&#xff0c;这一天&#xff0c;翘首以待的《 项 目管理知识体系指南 》&#xff08;PMBOK&#xff09;第七版终于发布了。 总体而言&#xff0c;PMBOK第七版集百家之所长&#xff0c;成一…

【Scrapy】Scrapy教程6——提取数据

前一小节我们拿到了页面的数据,那页面中那么多内容,我们想要其中的部分内容,该如何获取呢?这就需要对我们下载到的数据进行解析,提取出来想要的数据,这节就讲讲如何提取数据。 引入 我们编辑保存下来的shouye.html文件看下,发现这是什么鬼,全是如下图的代码。 没错…

golang panic信息捕获

背景 我们的日志接入阿里云sls平台&#xff0c;但是&#xff0c;日志是以json的格式存储在阿里云sls平台上&#xff0c;程序中产生的error,info等日志都可以实现以json的格式打印。但是&#xff0c;golang程序中产生的panic信息本身不是以json的格式输出&#xff0c;这就导致p…

一周学会Flask3 Python Web开发-http响应状态码

锋哥原创的Flask3 Python Web开发 Flask3视频教程&#xff1a; 2025版 Flask3 Python web开发 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili 在Flask程序中&#xff0c;客户端发出的请求触发相应的视图函数&#xff0c;获取返回值会作为响应的主体&#xff0c;最后生成…

goland无法debug项目

1、其实个原因是因为正在使用的Delve调试器版本太旧&#xff0c;无法兼容当前的Go语言版本1.2。Delve是Go语言的一个调试工具&#xff0c;用于提供源码级别的调试功能。Go语言每隔一段时间会发布新版本&#xff0c;而相应的调试器Delve也可能会更新以提供新的特性或修复已知问题…

Python VsCode DeepSeek接入

Python VsCode DeepSeek接入 创建API key 首先进入DeepSeek官网&#xff0c;https://www.deepseek.com/ 点击左侧“API Keys”&#xff0c;创建API key&#xff0c;输出名称为“AI” 点击“创建"&#xff0c;将API key保存&#xff0c;复制在其它地方。 在VsCode中下载…

Ubuntu22.04.6如何固定ip地址

Ubuntu22.04.6如何固定ip地址 主要参见这篇博客 ubuntu 桌面版如何设置固定IP地址_ubuntu桌面版如何修改ip-CSDN博客 1.先查看一下当前的IP是多少

腿足机器人之十- SLAM地图如何用于运动控制

腿足机器人之十- SLAM地图如何用于运动控制 腿足机器人SLAM地图的表示与处理全局路径规划&#xff1a;地形感知的路径搜索基于A*的三维路径规划基于RRT*的可行步态序列生成 局部运动规划&#xff1a;实时步态调整与避障动态窗口法的腿足适配模型预测控制&#xff08;MPC&#x…

毕业项目推荐:基于yolov8/yolov5/yolo11的果蔬检测识别系统(python+卷积神经网络)

文章目录 概要一、整体资源介绍技术要点功能展示&#xff1a;功能1 支持单张图片识别功能2 支持遍历文件夹识别功能3 支持识别视频文件功能4 支持摄像头识别功能5 支持结果文件导出&#xff08;xls格式&#xff09;功能6 支持切换检测到的目标查看 二、数据集三、算法介绍1. YO…

pyside6学习专栏(二):程序图像资源的加载方式

pyside6中的QLabel控件可以加载图像和gif动画&#xff0c;可以直接从外部文件加载&#xff0c;也可以从QRC类型的文件(实际是一脚本文件)经编绎生成对应的资源.PY模块文件(就是将qrc文本中指定的资源文件的16制内容写入.py文件)来使用&#xff0c;本文对两种方式作了一简单的示…

如何在 VS Code 中快速使用 Copilot 来辅助开发

在日常开发中&#xff0c;编写代码往往是最耗时的环节之一。而 GitHub Copilot&#xff0c;作为一款 AI 编码助手&#xff0c;可以帮助开发者 自动补全代码、生成代码片段&#xff0c;甚至直接编写完整的函数&#xff0c;大幅提升编码效率。那么&#xff0c;如何在 VS Code 中快…

DeepSeek-R1论文阅读及本地调用

前言 DeepSeek已经火了一段时间了&#xff0c;对于这项“国运级”的技术成果&#xff0c;即便研究的不是这个方向&#xff0c;也不免好奇前来看看。本文将先解析一下DeepSeek-R1这篇论文&#xff0c;再对DeepSeek的本地部署使用进行研究配置。 论文标题&#xff1a;DeepSeek-…

自然语言处理:第九十二章 chatBI 经验(转载)

本人项目地址大全&#xff1a;Victor94-king/NLP__ManVictor: CSDN of ManVictor 原文连接: 一文分享 ChatBI 实践经验 写在前面: 笔者更新不易&#xff0c;希望走过路过点个关注和赞&#xff0c;笔芯!!! 写在前面: 笔者更新不易&#xff0c;希望走过路过点个关注和赞&#x…

体验用ai做了个python小游戏

体验用ai做了个python小游戏 写在前面使用的工具2.增加功能1.要求增加视频作为背景。2.我让增加了一个欢迎页面。3.我发现中文显示有问题。4.我提出了背景修改意见&#xff0c;欢迎页面和结束页面背景是视频&#xff0c;游戏页面背景是静态图片。5.提出增加更多游戏元素。 总结…

懒人精灵本地离线卡密验证系统教程(不联网、安全稳定、省钱、永久免费、无任何限制)

1.合集懒人精灵本地离线卡密验证系统教程(不联网、安全稳定、省钱、永久免费、无任何限制)&#xff1a;https://www.bilibili.com/video/BV1M6rdYEEog/ 备注&#xff1a; 1.本地离线卡密采用最安全的非对称加解密技术&#xff0c;设备id采用最安全多重混合加密不可逆技术生成&…

前后端项目部署服务器(传统部署和Docker部署)

内外网 开发环境连外网&#xff08;8.140.26.187&#xff09;&#xff0c;测试/生产环境连内网&#xff08;172.20.59.17&#xff09; 内外网地址不同&#xff0c;但指定的库是同一个 内网IP地址范围包括&#xff1a; 10.0.0.0 到 10.255.255.255172.16.0.0 到 172.31.2551…

python-leetcode 39.二叉树的直径

题目&#xff1a; 给定一棵二叉树的根节点&#xff0c;返回该树的直径。 二叉树的直径是指中间任意两个节点之间最长路径的长度。这条路径可能经过也可能不经过根节点root 两节点之间路径的长度由他们之间的边数表示 方法一&#xff1a;深度优先搜索 一条路径的长度为该路…

【分布式理论11】分布式协同之分布式事务(一个应用操作多个资源):从刚性事务到柔性事务的演进

文章目录 一. 什么是分布式事务&#xff1f;二. 分布式事务的挑战三. 事务的ACID特性四. CAP理论与BASE理论1. CAP理论1.1. 三大特性1.2. 三者不能兼得 2. BASE理论 五. 分布式事务解决方案1. 两阶段提交&#xff08;2PC&#xff09;2. TCC&#xff08;Try-Confirm-Cancel&…

配置Api自动生成

我的飞书:https://rvg7rs2jk1g.feishu.cn/docx/TVlJdMgYLoDJrsxAwMgcCE14nxt 使用Springfox Swagger生成API&#xff0c;并导入Postman&#xff0c;完成API单元测试 Swagger: 是一套API定义的规范&#xff0c;按照这套规范的要求去定义接口及接口相关信息&#xff0c;再通过可…