【Java EE】多线程(二)Thread 类与常用方法

封面

📚博客主页:爱敲代码的小杨.

✨专栏:《Java SE语法》 | 《数据结构与算法》 | 《C生万物》 |《MySQL探索之旅》 |《Web世界探险家》

❤️感谢大家点赞👍🏻收藏⭐评论✍🏻,您的三连就是我持续更新的动力❤️

🙏小杨水平有限,欢迎各位大佬指点,相互学习进步!

文章目录

  • 0. 前言
  • 1. Thread 的常见构造方法
  • 2. Thread 类常见属性
    • 2.1 ID
    • 2.2 名称
    • 2.3 状态
    • 2.4 优先级
    • 2.5 是否后台线程
    • 2.6 是否存活
    • 2.7 是否被中断
  • 3. 启动线程-start()

0. 前言

Thread 类是 JVM 用来创建和管理线程的类,也就是说每个线程都有唯一一个Thread 对象与之关联。

1. Thread 的常见构造方法

方法作用
Thread()创建线程对象
Thread(String name)创建线程对象,并命名
Thread(Runnable target)使用 Runnable 对象创建线程对象
Thread(Runnable target, String name)使用 Runnable 对象创建线程对象,并命名
class MyRunnable implements Runnable{@Overridepublic void run() {}
}public class demo1 {public static void main(String[] args) {Thread t1 = new Thread();System.out.println(t1.getName());Thread t2 = new Thread(new MyRunnable());System.out.println(t2.getName());Thread t3 = new Thread("t3线程");System.out.println(t3.getName());Thread t4 = new Thread(new MyRunnable(), "t4线程");System.out.println(t4.getName());}
}

运行结果:
image.png

2. Thread 类常见属性

属性方法
IDgetId()
名称getName()
状态getState()
优先级getPriority()
是否后台线程isDaemon()
是否存活isAlive()
是否被中断isInterruupted()

2.1 ID

ID 是线程的唯⼀标识,不同线程不会重复

public class demo2 {public static void main(String[] args) {Thread t1 = new Thread();System.out.println(t1.getName() + "ID:" + t1.getId());Thread t2 = new Thread("t2线程");System.out.println(t2.getName() + "ID:" + t2.getId());}
}

运行结果:
image.png
【注意】:这里的 ID 和 pcb 一一对应,但是这里的 ID 和 系统的中 pcb 上的 ID 是不同的体系(Java代码无法获取到 pcb 中的 ID),JVM 自己搞了一套 ID 体系

比如:我们去上班,在A公司,你的是工号xxxx,后来去到了B公司,你的工号是yyyy,人都是同一个人,在不同的体系中,工号就变了

2.2 名称

public class demo2 {public static void main(String[] args) {Thread t1 = new Thread();System.out.println(t1.getName());Thread t2 = new Thread("t2线程");System.out.println(t2.getName());Thread t3 = new Thread();t3.setName("t3线程"); // 设置线程名称System.out.println(t3.getName());}
}

运行结果:
image.png
如果线程没有命名, 默认为 Thread-0, Thread-1...

2.3 状态

后面具体介绍…(下集预告)

2.4 优先级

虽然 Java 提供了优先级接口,实际上就算修改了优先级,现象也不明显,修改了优先级是一回事,系统调度又是另一回事,这里的优先级只能是一个“建议参考”,具体还是系统以自身为准。
本质上还是因为调度这个事情,系统就一言堂了,我们很难干预到。

public class demo9 {public static void main(String[] args) {Thread t1 = new Thread(() -> {while (true) {System.out.println("hello Thread1");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}});Thread t2 = new Thread(() -> {while (true) {System.out.println("hello Thread2");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}});t1.setPriority(Thread.MIN_PRIORITY); // 设置最低优先级t2.setPriority(Thread.MAX_PRIORITY); // 设置最高优先级t1.start();t2.start();}
}

运行结果:
image.png


image.png
从上图可以看出无论是否设置优先级,运行结果都差不多

2.5 是否后台线程

前台线程: 这种线程如果不运行结束的话, 此时 Java 进程是一定不会结束的
后台线程: 这样的线程, 即使继续在执行, 也不能阻止 Java 进程结束

举例: 酒桌文化
人物: 组局人(前台线程) 小杨(后台线程)
一桌人吃饭, 组局人(前台线程)可以掌握整个宴席(线程)的结束, 当组局人(前台线程)说宴席(线程)结束就结束了, 即使小杨(后台线程)还没有吃完,即使我还没有吃饱,也得撤了(当有多个组局人(多个前台线程)的时候, 当全部的组局人都不吃了, 宴席(线程)就结束了), 如果小杨先吃完,我想先溜(后台线程结束),我溜了对于整个宴席没有任何影响.
当全部的前台线程都结束了, 线程就结束了, 无论后台线程是否执行结束
当后台线程执行结束了, 要等到全部的前台线程结束, 线程才结束

在 Java 代码中, main 线程就是前台线程, 另外创建出来的线程也是前台线程, 可以通过 setDaemon 方法把线程设置为后台线程.
代码:

public class demo10 {public static void main(String[] args) {Thread t1 = new Thread(() -> {for (int i = 0; i < 5; i++) {System.out.println("hello Thread1");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}});t1.setDaemon(true); // t1线程设置为后台线程t1.start();}
}

运行结果:
image.png

【注意】:此处也有一定概率,出现 t1 打印一次,然后结束进程的情况
这种情况就要看是 main 先执行结束,还是 t1 先执行打印1一次(线程之间是抢占式执行的,调度顺序是不确定的)


image.png

2.6 是否存活

是否存活: 指的是系统中(pcb) 是否还存在
Thread 对象的生命周期和 pcb 的生命周期是不一定完全一样的
image.png
代码:

public class demo11 {public static void main(String[] args) {Thread t1 = new Thread(() -> {try {Thread.sleep(2000);} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println("线程执行完毕!");});// 判断 t1线程是否存活System.out.println(t1.isAlive());t1.start();System.out.println(t1.isAlive());// 等待线程执行结束try {t1.join();} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println(t1.isAlive());}
}

运行结果:
image.png

2.7 是否被中断

中断线程,在 Java 中,都只是“提醒”,“建议”,真正要不要终止,还得线程本体来进行决定的

t1线程正在执行,其他线程,只能提醒一下 t1 是不是要终止了,t1 收到这样的提醒之后,也还是得自己决定的

常见的方式以下两种:

  1. 通过共享的标记来进行沟通
  2. 调用 interrupt() 方法来通知

示例一:

public class demo12 {private static boolean isRunning = true;public static void main(String[] args) {Thread t1 = new Thread(() -> {while (isRunning) {System.out.println("hello thread");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}System.out.println("t1线程结束");});t1.start(); // 启动线程// 等待3stry {Thread.sleep(3000);} catch (InterruptedException e) {throw new RuntimeException(e);}// 3s 后, 主线程修改 isRunning 的值,从而通知 t1 结束System.out.println("控制 t1 线程结束");isRunning = false;}
}

运行结果:
image.png
示例二:

public class demo13 {public static void main(String[] args) {Thread t1 = new Thread(() -> {while (!Thread.currentThread().isInterrupted()) {System.out.println("hello thread");try {Thread.sleep(1000);} catch (InterruptedException e) {//throw new RuntimeException(e);//e.printStackTrace();System.out.println("线程即将结束");break; // !!!注意此处的break}}System.out.println("t1线程结束");});t1.start();try {Thread.sleep(3000);} catch (InterruptedException e) {throw new RuntimeException(e);}t1.interrupt();}
}

运行结果:
image.png
Thread 收到通知的方式有两种:

  1. 如果线程因为调⽤ wait/join/sleep 等⽅法⽽阻塞挂起,则以 InterruptedException 异常的形式通知,清除中断标志
    • 当出现 InterruptedException 的时候, 要不要结束线程取决于 catch 中代码的写法. 可以选择忽略这个异常, 也可以跳出循环结束线程.
  2. 否则,只是内部的⼀个中断标志被设置,Thread 可以通过
    • Thread.currentThread().isInterrupted() 判断指定线程的中断标志被设置,不清除中断标志

这种方式通知收到的更及时,即使线程正在 sleep 也可以马上收到。

3. 启动线程-start()

之前我们已经看到了如何通过重写 run() 方法创建⼀个线程对象,但线程对象被创建出来并不意味着线程就开始运行了。

举例

  • 重写 run() 方法是提供给线程要做的事情的指令清单
  • 线程对象可以认为是把 小杨、肯德滑稽叫过来点餐
  • 而调用 start() 方法,,就是喊一声“去制作吧”,线程才真正独立来执行

调用 start() 方法, 才真的在操作系统的底层创建出一个线程.

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Qt QML】Frame组件

Frame&#xff08;框架&#xff09;包含在&#xff1a; import QtQuick.Controls继承自Pane控件。用于在可视框架内布局一组逻辑控件。简单来说就是用来包裹和突出显示其他可视元素。Frame不提供自己的布局&#xff0c;但需要自己对元素位置进行设置和定位&#xff0c;例如通过…

【JavaEE 初阶(二)】线程安全问题

❣博主主页: 33的博客❣ ▶️文章专栏分类:JavaEE◀️ &#x1f69a;我的代码仓库: 33的代码仓库&#x1f69a; &#x1faf5;&#x1faf5;&#x1faf5;关注我带你了解更多线程知识 目录 1.前言2.synchronized2.1例子2.2synchronized修饰代码块2.3 synchronized修饰方法2.4sy…

python中怎么清屏

一、“Windows命令行窗口”下清屏&#xff0c;可用下面两种方法&#xff1a; 第一种方法&#xff0c;在命令行窗口输入&#xff1a; import os ios.system("cls") 第二种方法&#xff0c;在命令行窗口输入&#xff1a; import subprocess isubprocess.call("cl…

数据结构--链表进阶面试题

在链表题目开始之前我们来复习一道数组元素的逆序问题&#xff1a; 给定一个整数数组 nums&#xff0c;将数组中的元素向右轮转 k 个位置&#xff0c;其中 k 是非负数。 提示&#xff1a; 1 < nums.length < 10^5-2^31 < nums[i] < 2^31 - 10 < k < 10^5 思…

微信小程序之搜索框样式(带源码)

一、效果图&#xff1a; 点击搜索框&#xff0c;“请输入搜索内容消失”&#xff0c;可输入关键字 二、代码&#xff1a; 2.1、WXML代码&#xff1a; <!--搜索框部分--><view class"search"><view class"search-btn">&#x1f50d;&l…

QT5之事件——包含提升控件

事件概述 信号就是事件的一种&#xff0c;事件由用户触发&#xff1b; 鼠标点击窗口&#xff0c;也可以检测到事件&#xff1b;产生事件后&#xff0c;传给事件处理&#xff0c;判断事件类型&#xff0c;后执行事件相应函数&#xff1b; 类似单片机的中断&#xff08;中断向量…

Docker 入门与实践:从零开始构建容器化应用环境

Docker 一、docker常用命令docker ps 格式化输出Linux设置命令别名 二、数据卷相关命令挂载到默认目录&#xff08;/var/lib/docker&#xff09;挂载到本地目录 三、自定义镜像Dockerfile构建镜像的命令 四、网络自定义网络 五、DockerCompose相关命令 一、docker常用命令 dock…

Superset二次开发之Legend功能优化

背景 Legend数据太长,影响整体图表体验,为改善用户体验,需要实现:1.数据省略展示,‘...’表示,鼠标悬停时,展示完整信息 2:文本内容从左向右滚动展示 柱状图优化 柱状图来自第三方Echarts插件,效果展示 功能核心在于红框的内容 option = {tooltip: {trigger: item,ax…

软件杯 深度学习的水果识别 opencv python

文章目录 0 前言2 开发简介3 识别原理3.1 传统图像识别原理3.2 深度学习水果识别 4 数据集5 部分关键代码5.1 处理训练集的数据结构5.2 模型网络结构5.3 训练模型 6 识别效果7 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 深度学习…

Vue3+Nuxt3 从0到1搭建官网项目(SEO搜索、中英文切换、图片懒加载)

Vue2Nuxt2 从 0 到1 搭建官网~ Vue3Nuxt3 从0到1搭建官网项目 安装 Nuxt3&#xff0c;创建项目初始化的 package.json项目结构初始化项目pages 文件下创建index.vue引入sass修改 app.vue 文件查看效果 配置公共的css、metaassets下的cssreset.scss 重置文件common.scss 配置nux…

CTF-WEB(MISC)

安全攻防知识——CTF之MISC - 知乎 CTF之MISC杂项从入门到放弃_ctf杂项 你的名字-CSDN博客 CTF MICS笔记总结_archpr 掩码攻击-CSDN博客 一、图片隐写 CTF杂项---文件类型识别、分离、合并、隐写_ctf图片分离-CSDN博客 EXIF&#xff08;Exchangeable Image File&#xff09;是…

考虑极端天气线路脆弱性的配电网分布式电源和储能优化配置模型

1 主要内容 程序主要参考《考虑极端天气线路脆弱性的配电网分布式电源配置优化模型-马宇帆》&#xff0c;针对极端天气严重威胁配电网安全稳定运行的问题。基于微气象、微地形对配电网的线路脆弱性进行分析&#xff0c;然后进行分布式电源接入位置与极端天气的关联性分析&…

​【收录 Hello 算法】第 3 章 数据结构

第 3 章 数据结构 Abstract 数据结构如同一副稳固而多样的框架。 它为数据的有序组织提供了蓝图&#xff0c;算法得以在此基础上生动起来。 本章内容 3.1 数据结构分类3.2 基本数据类型3.3 数字编码 *3.4 字符编码 *3.5 小结

Java | Leetcode Java题解之第59题螺旋矩阵II

题目&#xff1a; 题解&#xff1a; class Solution {public int[][] generateMatrix(int n) {int num 1;int[][] matrix new int[n][n];int left 0, right n - 1, top 0, bottom n - 1;while (left < right && top < bottom) {for (int column left; co…

uniapp:K线图,支持H5,APP

使用KLineChart完成K线图制作,完成效果: 1、安装KLineChart npm install klinecharts2、页面中使用 <template><view class="index"><!-- 上方选项卡 --><view class="kline-tabs"><view :style="{color: current==ite…

《动手学深度学习(Pytorch版)》Task03:线性神经网络——4.29打卡

《动手学深度学习&#xff08;Pytorch版&#xff09;》Task03&#xff1a;线性神经网络 线性回归基本元素线性模型损失函数随机梯度下降 正态分布与平方损失 线性回归的从零开始实现读取数据集初始化模型参数定义模型定义损失函数定义优化算法训练 线性回归的简洁实现读取数据集…

【c++】Resharper 去掉中文注释拼写

参考大神&#xff1a; Resharper 去掉注释拼写 reshaper的中文注释一堆下划线&#xff0c;看的很累、很乱&#xff1a; options 里 在code inspetion里 搜索 去掉 Typo in comment 就可以不在中文注释提示 重启vs reshaperd 中文注释下划线没了。小番茄的还在。

jsPDF + html2canvas + Vue3 + ts项目内,分页导出当前页面为PDF、A 页面内导出 B 页面的内容为PDF,隐藏导出按钮等多余元素

jsPDF html2canvas Vue3 ts Arco Design项目&#xff0c;分页导出当前页面为PDF、A 页面内导出 B 页面的内容为PDF&#xff0c;隐藏导出按钮等多余元素… 1.下载所需依赖 pnpm install --save html2canvaspnpm install --save jspdf引入依赖 <script setup lang"…

2010NOIP普及组真题 3. 导弹拦截

线上OJ&#xff1a; 一本通&#xff1a;http://ybt.ssoier.cn:8088/problem_show.php?pid1951 核心思想&#xff1a; 1、我们把导弹分为区间1和区间2来看。1#拦截区间1&#xff0c;2#拦截区间2。 2、则&#xff1a;1#的拦截半径为区间1 中 最远的导弹&#xff0c;而2#的拦截半…

关于 c++的模板库中的数组模板 is_array_v的测试

&#xff08;1&#xff09;该模板的源代码如下&#xff1a; template <class> // determine whether type argument is an array bool is_array_v false;template <class _Ty, size_t _Nx> bool is_array_v<_Ty[_Nx]> true;template <class _Ty>…