当前位置: 首页 > news >正文

Java【多线程基础2】 Thread类 及其常用方法

文章目录

  • 前言
  • 一、Thread类
    • 1, 构造方法
    • 2, 常用成员属性
    • 3, 常用成员方法
      • 3.1, start 启动线程
      • 3.2, interrupt 中断线程 (重点)
        • 3.2.1, 手动设置标记位
        • 3.2.2, 使用内置标记位
        • 3.3.3, interrupt 方法 的作用
      • 3.3 sleep 休眠线程
      • 3.4, jion 等待线程
      • 3.5 获取当前线程的引用
  • 总结


前言

各位读者好, 我是小陈, 这是我的个人主页
小陈还在持续努力学习编程, 努力通过博客输出所学知识
如果本篇对你有帮助, 烦请点赞关注支持一波, 感激不尽
希望我的专栏能够帮助到你:
JavaSE基础: 从数据类型类和对象, 封装继承多态, 接口, 综合小练习图书管理系统
Java数据结构: 顺序表, 链表, 二叉树, , 哈希表等 (正在持续更新)
JavaEE初阶: 多线程, 网络编程, html, css, js, severlet, http协议, linux等(正在持续更新)

上篇介绍了[多线程基础篇1], 主要内容 : 线程 的概念, 线程 和 进程 的区别, 以及如何创建线程
本篇继续介绍多线程相关的基础内容, 内容较多, 分为若干篇持续分享


提示:是正在努力进步的小菜鸟一只,如有大佬发现文章欠佳之处欢迎批评指点~ 废话不多说,直接上干货!

一、Thread类

Thread类是 JVM 用来管理线程的一个类,换句话说,每个线程都有一个唯一的 Thread类 的对象与之关联

每一个线程, 都需要被描述(具体被描述什么, 下面再说), Thread类 的对象就是用来描述一个线程的

学习一个类, 要从它的构造方法学起


1, 构造方法

1, 无参构造方法 :

在上一篇介绍线程的创建方式时, 使用到了匿名内部类继承Thread, 重写 run 方法的方式, 这就是无参构造法的使用

        Thread thread = new Thread() {@Overridepublic void run() {System.out.println("一个新的thread线程");}};

2, 一个参数的构造方法 : 参数是 String 类型的 name , 表示线程的名字

其实就是方法1 的创建线程方式, 构造方法参数可以传递一个"name", 唯一的作用只是程序员知道自己创建的线程是谁, 方便多线程中代码调试

		// 给这个线程命名为"喜羊羊"Thread thread = new Thread("喜羊羊") {@Overridepublic void run() {System.out.println("一个新的thread线程");}};thread.start();// 输出线程的名字System.out.println("thread线程的名字是: " +  thread.getName());

在这里插入图片描述

3, 一个参数的构造方法 : 参数是 Runnable 对象

在上一篇介绍线程的创建方式时, 使用到了lambda表达式的方式, 本质上就是匿名内部类实现了 Runnable 接口, 重写 run 方法, 把 Runnable 对象作为参数

        Thread thread = new Thread( () -> {while(true) {System.out.println("一个新的thread线程");}});

4, 两个参数的构造方法 : 一个是 Runnable 接口, 一个是 String 类型的 name

使用 lambda 表达式传参之后, 再传入一个字符串即可

        Thread thread = new Thread(() -> {System.out.println("一个新的thread线程");}, "美羊羊"); // 给这个线程命名为"美羊羊"thread.start();// 输出线程的名字System.out.println("thread线程的名字: " + thread.getName());

在这里插入图片描述


2, 常用成员属性

1, ID . 获取 ID 使用 getId()
表示线程的唯一身份表示, 不会重复

2, 名称 . 获取名称使用 getName()
表示线程的名字, 对代码调试有帮助

3, 状态 . 获取状态使用 getState()
表示线程所处的情况, 下面会详细讨论

4, 优先级 . 获取优先级使用 getPriority()
优先级高线程的理论上会被优先调度, 但是线程是操作系统进行调度执行的基本单位
所以线程被调度的顺序归根结底还是操作系统决定的

5, 是否为后台线程(默认为前台) . 获取是否为后台线程使用 isDaemon()
前台线程会阻止进程的结束, 后台线程不会, 啥意思?
java 进程中的所有前台线程都结束 java 进程才能结束, 后台线程不管是否结束, java 进程该结束就结束

可以通过 setDaemon() 把线程改为后台线程(true)

6, 是否存活 . 获取是否存活使用 isAlive()
run 方法结束了, 说明线程执行完了, 就不存在了(不存活了), 或者 run 方法执行之前, 线程也不存在(不存活)

7, 是否被中断 . 获取是否被中断使用 isInterrupted()
这个下面介绍 interrupt 方法时会介绍到

代码展示:

		Thread thread = new Thread(() -> {}, "美羊羊");System.out.println("-----调用 start 方法之前-----");System.out.println("thread线程 的状态 : " + thread.getState() + " (这是啥意思? 下面会介绍到)");System.out.println("thread线程 是否存活 : " + thread.isAlive() + " 此时 thread线程 不存在, 所以不存活");System.out.println(" ");thread.start();System.out.println("-----调用 start 方法时-----");System.out.println("thread线程 是否存活 : " + thread.isAlive() + " 此时 thread线程 正在执行, 所以不存活");System.out.println(" ");System.out.println("-----调用 start 方法之后-----");// 1, 获取thread线程的IDSystem.out.println("1, thread线程 的 id : " + thread.getId());// 2, 获取thread线程的名字System.out.println("2, thread线程 的名字 : " + thread.getName());// 3, 获取thread线程的状态System.out.println("3, thread线程 的状态 : " + thread.getState() + " (这是啥意思? 下面会介绍到)");// 4, 获取thread线程的优先级System.out.println("4, thread线程 的优先级 : " + thread.getPriority());// 5, thread线程是否为后台线程System.out.println("5, thread线程 是否为后台线程 : " + thread.isDaemon() + "默认都是false");// 6, thread线程是否存活System.out.println("6, thread线程 是否存活 : " + thread.isAlive() + " 此时 thread线程 已经执行完了, 所以不存活");// 7, thread线程是否被中断System.out.println("7, thread线程 是否被中断 : " + thread.isInterrupted());

在这里插入图片描述


3, 常用成员方法

3.1, start 启动线程

这个方法已经使用过很多次了, 再做一些强调 :

重写了 run 方法只是用代码描述了线程要执行什么操作
上篇介绍了很多方式用来创建线程对象, 创建了线程对象不代表线程开始执行
程序员自己调用 run 方法虽然也会执行方法体中的代码, 但并没有启动新的线程
调用 start 方法才会启动一个线程, 这个被创建出来的线程才会真正独立执行


3.2, interrupt 中断线程 (重点)

3.2.1, 手动设置标记位

如果在 run 方法中执行循环打印, 循环条件为 true , 那么调用 start 方法启动线程后, 这个线程将无法结束

如果我们提前设置一个标记位 flag 为 false, 循环条件为 !flag , 并且每执行一次打印, 就休眠 1000 毫秒, 此时线程仍无法结束

使用 sleep 方法需要使用 try-catch 语句捕获一个 InterruptedException异常, 表示休眠期间被打断就会抛出异常
catch 语句中的 e.printStackTrace(); 就是在出现异常时用来打印调用栈信息

	// 成员属性 flagprivate static boolean flag = false;public static void main(String[] args)  {Thread thread = new Thread(() -> {while(!flag) {System.out.println("一个新的thread线程");try {// 打印一次, 休眠 1 秒 Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}});

然后, 令主线程休眠 3000 毫秒后把 flag 设置为 true,

        thread.start();try {Thread.sleep(3000);flag = true;} catch (InterruptedException e) {e.printStackTrace();}

此时 thread 线程中的循环不满足循环条件, 就会结束, 主线程 和 thread 线程的并发执行结果如下 : 在这里插入图片描述


3.2.2, 使用内置标记位

上面是我们手动设置了标记位
而 Thread类 的常见属性中提到的 isInterrupted(), 就是内置的标记位, 默认为 false , 类似于刚刚代码里的 flag, 我们用 isInterrupted() 替换上面的 flag :

			// 省略其他代码while(!Thread.currentThread().isInterrupted()) {// 省略其他代码

Thread . currentThread() 是获取当前线程的示例, 也就是 thread
所以 : Thread . currentThread() . isInterrupted() 等同于 thread . isInterrupted()
只不过此时还没有完成对 thread 的初始化, 不能如后者那样写

接下来主线程中如何修改标记为呢? 就是使用 interrupt 方法 直接中断线程

		// 省略其他代码try {Thread.sleep(3000);thread.interrupt();} catch (InterruptedException e) {e.printStackTrace();}

程序会如何执行呢? 需要先看看 interrupt 方法 到底有什么用


3.3.3, interrupt 方法 的作用

1, 会把标志位设为 true, 执行完 interrupt 之后 isInterrupted 的值就被设为 true 了
2, 如果线程处于阻塞状态, 就会取消阻塞状态, 上述代码中因为 sleep 方法, thread线程 会处于阻塞态(休眠), interrupt 就会让休眠结束, sleep 抛出异常,

所以, 按理说, 这个并发执行的程序最终会以一个异常结束
在这里插入图片描述

可以看到, catch 语句捕获了异常, 说明线程确实被打断了, 可是为什么线程没有结束, 还在循环打印呢 ? 原因是因为 sleep 方法


3.3 sleep 休眠线程

关于 sleep 方法的使用 以上代码已经用过很多次了, 这里再做个总结 :
参数为毫秒, 表示 sleep 方法执行后, 线程休眠多久
需要用 try-catch 捕获 InterruptedException 这个受查(编译时)异常, 如果休眠时被中断, 就会抛出异常

但是, sleep方法 还有一个重要操作 ! !
在休眠时如果被唤醒, sleep方法会自动把标志位清空: 设置成 false

这就导致了在上述代码中, 为啥调用了 interrupt 方法后, 线程没有真正被中断, 就是因为标志位又被设置成了 false , 所以程序仍然会执行循环

sleep 方法为什么会这么做呢?

原因是, Thread类 并不希望线程执行了 interrupt 方法之后就立即被中断, 这样是很霸道很强硬的做法
它希望的效果是, interrupt 方法, 仅仅起到一个 “提示” 或者 “通知” 的作用, 然后由程序员编写代码, 用代码逻辑来控制线程是立即结束, 还是等一会再结束, 还是无视这个 “通知”

比如我女朋友让我别刷抖音了, 陪她出门逛街, 我完全可以立即关掉抖音
但如果我此时在努力敲代码, 有很重要的学习任务, 我可以和她商量, 能不能等我学习完再去
如果我无论什么状态下都立即中断手头的事儿, 显然是不合理的

站在我的角度来说, 只有我自己最了解, 最关心自己, 知道现在应该做什么

站在程序员的角度上, 只有程序员最了解, 最关心自己写的代码, 知道当前的代码是否应该结束, 所以交给程序员决定何时中断才是最优解

那么在上述代码中, 如何实现立即中断呢? 只需要在捕获异常之后加一个 break 即可

				// 省略其他代码} catch (InterruptedException e) {e.printStackTrace();break;}// 省略其他代码

在这里插入图片描述


3.4, jion 等待线程

有的时候, 多个线程不能满足并发的条件, 可能需要等某个线程执行完再并发执行

例如我要和女朋友去约会, 我应该去她家楼下接她, 如果我到她家楼下后, 她还在化妆, 我应该等她下楼之后再一起去约会

我们先再复习一下多线程的并发执行效果 :

        Thread thread = new Thread( () -> {// 循环打印 5 次for (int i = 0; i < 5; i++) {System.out.println("thread线程");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}});thread.start();// 循环打印 5 次for (int i = 0; i < 5; i++) {System.out.println("主线程");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}

在这里插入图片描述

两条打印语句交替执行, 如果我在调用 start 方法启动 thread线程 之后, 再写一个 thread.join(), 会发生什么呢?

		// 省略其他代码thread.start();thread.join();// 省略其他代码

在这里插入图片描述
可以看到, 当 thread线程 执行完了所有的循环打印之后, 主线程 才开始循环打印, 说明此时, 主线程 是等待 thread线程 结束之后才执行的

所以 : 主线程调用 thread.join 就是 主线程 等待 thread线程

3.5 获取当前线程的引用

上面已经使用过了, 这是一个静态方法, 会获取当前线程的引用, 然后可以继续进行其他操作

例如, 在 run 方法中执行完打印语句之后, 再打印一下当前线程的名字

        Thread thread = new Thread( () -> {for (int i = 0; i < 5; i++) {System.out.print("thread线程");System.out.println(" 我的名字叫 : " + Thread.currentThread().getName());}},"懒羊羊");thread.start();

在这里插入图片描述


总结

以上就是本篇的全部内容, 主要介绍了

Thread类中的 : 构造方法, 成员属性, 成员方法
其中, interrupt方法 和 sleep方法 有个特殊点, 需要重点理解

如果本篇对你有帮助,请点赞收藏支持一下,小手一抖就是对作者莫大的鼓励啦😋😋😋~


上山总比下山辛苦
下篇文章见

相关文章:

Java【多线程基础2】 Thread类 及其常用方法

文章目录前言一、Thread类1, 构造方法2, 常用成员属性3, 常用成员方法3.1, start 启动线程3.2, interrupt 中断线程 (重点)3.2.1, 手动设置标记位3.2.2, 使用内置标记位3.3.3, interrupt 方法 的作用3.3 sleep 休眠线程3.4, jion 等待线程3.5 获取当前线程的引用总结前言 各位读…...

JVM调优实战及常量池详解

目录 阿里巴巴Arthas详解 Arthas使用场景 Arthas使用 GC日志详解 如何分析GC日志 CMS G1...

ChatGPT研究分析:GPT-4做了什么

前脚刚研究了一轮GPT3.5&#xff0c;OpenAI很快就升级了GPT-4&#xff0c;整体表现有进一步提升。追赶一下潮流&#xff0c;研究研究GPT-4干了啥。本文内容全部源于对OpenAI公开的技术报告的解读&#xff0c;通篇以PR效果为主&#xff0c;实际内容不多。主要强调的工作&#xf…...

我为什么要写博客,写博客的意义是什么??

曾经何时我也不知道&#xff0c;怎样才能变成我自己所羡慕的大佬&#xff01;&#xff01;在一次次的CSDN阅读的过程中&#xff0c;结实了许多志同道合的人&#xff01;&#xff01;包过凉哥&#xff0c;擦姐……大佬&#xff0c;但是&#xff0c;很遗憾&#xff0c;与这些人只…...

ssm框架之spring:浅聊AOP

AOP&#xff08;Aspect Oriented Programming&#xff09;&#xff0c;是一种设计思想。先看一下百度百科的解释&#xff1a; 在软件业&#xff0c;AOP为Aspect Oriented Programming的缩写&#xff0c;意为&#xff1a;面向切面编程&#xff0c;通过预编译方式和运行期间动态…...

k8s详解

一、k8s中的yaml文件 JSON格式&#xff1a;主要用于api接口之间信息的传递YAML格式&#xff1a;主要用于配置和管理&#xff0c;YAML是一种简洁的非标记性语言&#xff0c;内容格式人性化 YAML格式&#xff1a; 大小写敏感使用缩进代表层级关系&#xff0c;不支持TAB制表符缩…...

计算机操作系统(第四版)第一章操作系统引论 1.1操作系统的目标和作用

第一章操作系统引论 1.1操作系统的目标和作用 什么是操作系统OS&#xff1f; 配置在计算机硬件上的第一层软件是对硬件的首次扩充。 是最重要的系统软件&#xff0c;其他系统软件应用软件都依赖于操作系统的支持。 操作系统主要作用&#xff1f; 管理计算机系统所有硬件设…...

git push解决办法: ! [remote rejected] master -> master (pre-receive hook declined)

项目经理远程创建了一个空项目&#xff0c;无任何内容&#xff0c;给我赋予的developer账号权限&#xff0c;本地改为后提交代码试了很多次都上传不上去&#xff0c;报错如下&#xff1a; ! [remote rejected] master -> master (pre-receive hook declined)先说结果&#x…...

jQuery 遍历方法总结

遍历方法有&#xff1a;1、add()&#xff0c;用于把元素添加到匹配元素的集合中&#xff1b;2、children()&#xff0c;用于返回被选元素的所有直接子元素&#xff1b;3、closest()&#xff0c;用于返回被选元素的第一个祖先元素&#xff1b;4、contents()&#xff0c;用于返回…...

OKHttp 源码解析(二)拦截器

游戏SDK架构设计之代码实现——网络框架 OKHttp 源码解析&#xff08;一&#xff09; OKHttp 源码解析&#xff08;二&#xff09;拦截器 前言 上一篇解读了OKHttp 的基本框架源码&#xff0c;其中 OKHttp 发送请求的核心是调用 getResponseWithInterceptorChain 构建拦截器链…...

如何修改设置浏览器内核模式

优先级&#xff1a; 强制锁定极速模式 >手动切换&#xff08;用户&#xff09;>meta指定&#xff08;开发者&#xff09;>浏览器兼容列表&#xff08;浏览器&#xff09; 需要用360安全浏览器14&#xff0c;chromium108内核&#xff0c;下载地址https://bbs.360.cn/t…...

30个Python常用小技巧

1、原地交换两个数字 1 2 3 4 x, y 10, 20 print(x, y) y, x x, y print(x, y) 10 20 20 10 2、链状比较操作符 1 2 3 n 10 print(1 < n < 20) print(1 > n < 9) True False 3、使用三元操作符来实现条件赋值 [表达式为真的返回值] if [表达式] else [表达式…...

ubuntu解决中文乱码

1、查看当前系统使用的字符编码 ~$ locale LANGen_US LANGUAGEen_US: LC_CTYPE"en_US" LC_NUMERIC"en_US" LC_TIME"en_US" LC_COLLATE"en_US" LC_MONETARY"en_US" LC_MESSAGES"en_US" LC_PAPER"en_US" …...

2022年全国职业院校技能大赛(中职组)网络安全竞赛试题——MYSQL安全测试解析(详细)

B-3任务三:MYSQL安全测试 *任务说明:仅能获取Server3的IP地址 1.利用渗透机场景kali中的工具确定MySQL的端口,将MySQL端口作为Flag值提交; 2.管理者曾在web界面登陆数据库,并执行了select <?php echo \<pre>\;system($_GET[\cmd\]); echo \</pre>\; ?…...

C++ map和unordered_map的区别

unordered_map 类模板和 map 类模板都是描述了这么一个对象&#xff1a;它是由 std::pair<const Key, value> 组成的可变长容器&#xff1b; 这个容器中每个元素存储两个对象&#xff0c;也就是 key - value 对。 1. unordered_map 在头文件上&#xff0c;引入 <unor…...

BCSP-玄子JAVA开发之JAVA数据库编程CH-04_SQL高级(二)

BCSP-玄子JAVA开发之JAVA数据库编程CH-04_SQL高级&#xff08;二&#xff09; 4.1 IN 4.1.1 IN 子查询 如果子查询的结果为多个值&#xff0c;就会导致代码报错解决方案就是使用 IN 关键字&#xff0c;将 替换成 IN SELECT …… FROM 表名 WHERE 字段名 IN (子查询);4.1.…...

学习java——②面向对象的三大特征

目录 面向对象的三大基本特征 封装 封装demo 继承 继承demo 多态 面向对象的三大基本特征 我们说面向对象的开发范式&#xff0c;其实是对现实世界的理解和抽象的方法&#xff0c;那么&#xff0c;具体如何将现实世界抽象成代码呢&#xff1f;这就需要运用到面向对象的三大…...

初阶数据结构 - 【单链表】

目录 前言&#xff1a; 1.概念 链表定义 结点结构体定义 结点的创建 2.链表的头插法 动画演示 代码实现 3.链表的尾插 动画演示 代码实现 4.链表的头删 动画演示 代码实现 5.链表的尾删 动画演示 代码实现 6.链表从中间插入结点 动画演示 代码实现 7.从单…...

第五周作业、第一次作业(1.5个小时)、练习一

一、创建servlet的过程没有太多好说的&#xff0c;唯一需要注意的就是&#xff1a;旧版本的servlet确实需要手动配置web.xml文件&#xff0c;但是servlet2.5以后,servlet的配置直接在Java代码中进行注解配置。我用的版本就不再需要手动去配置web.xml文件了&#xff0c;所以我只…...

【正点原子FPGA连载】 第三十三章基于lwip的tftp server实验 摘自【正点原子】DFZU2EG_4EV MPSoC之嵌入式Vitis开发指南

第三十三章基于lwip的tftp server实验 文件传输是网络环境中的一项基本应用&#xff0c;其作用是将一台电子设备中的文件传输到另一台可能相距很远的电子设备中。TFTP作为TCP/IP协议族中的一个用来在客户机与服务器之间进行文件传输的协议&#xff0c;常用于无盘工作站、路由器…...

Vim 调用外部命令学习笔记

Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...

HTML 语义化

目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案&#xff1a; 语义化标签&#xff1a; <header>&#xff1a;页头<nav>&#xff1a;导航<main>&#xff1a;主要内容<article>&#x…...

应用升级/灾备测试时使用guarantee 闪回点迅速回退

1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间&#xff0c; 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点&#xff0c;不需要开启数据库闪回。…...

云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地

借阿里云中企出海大会的东风&#xff0c;以**「云启出海&#xff0c;智联未来&#xff5c;打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办&#xff0c;现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...

如何在看板中有效管理突发紧急任务

在看板中有效管理突发紧急任务需要&#xff1a;设立专门的紧急任务通道、重新调整任务优先级、保持适度的WIP&#xff08;Work-in-Progress&#xff09;弹性、优化任务处理流程、提高团队应对突发情况的敏捷性。其中&#xff0c;设立专门的紧急任务通道尤为重要&#xff0c;这能…...

工业自动化时代的精准装配革新:迁移科技3D视觉系统如何重塑机器人定位装配

AI3D视觉的工业赋能者 迁移科技成立于2017年&#xff0c;作为行业领先的3D工业相机及视觉系统供应商&#xff0c;累计完成数亿元融资。其核心技术覆盖硬件设计、算法优化及软件集成&#xff0c;通过稳定、易用、高回报的AI3D视觉系统&#xff0c;为汽车、新能源、金属制造等行…...

NLP学习路线图(二十三):长短期记忆网络(LSTM)

在自然语言处理(NLP)领域,我们时刻面临着处理序列数据的核心挑战。无论是理解句子的结构、分析文本的情感,还是实现语言的翻译,都需要模型能够捕捉词语之间依时序产生的复杂依赖关系。传统的神经网络结构在处理这种序列依赖时显得力不从心,而循环神经网络(RNN) 曾被视为…...

【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分

一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计&#xff0c;提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合&#xff1a;各模块职责清晰&#xff0c;便于独立开发…...

【开发技术】.Net使用FFmpeg视频特定帧上绘制内容

目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法&#xff0c;当前调用一个医疗行业的AI识别算法后返回…...

Java多线程实现之Thread类深度解析

Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...