[JavaEE] Thread类及其常见方法

news2024/10/5 20:28:47


专栏简介: JavaEE从入门到进阶

题目来源: leetcode,牛客,剑指offer.

创作目标: 记录学习JavaEE学习历程

希望在提升自己的同时,帮助他人,,与大家一起共同进步,互相成长.

学历代表过去,能力代表现在,学习能力代表未来! 


目录

1.Thread 的常见构造方法

2.Thread 的几个常见属性

3. 启动一个线程

4. 中断一个线程

5. 等待一个线程

6. 获取当前线程引用

7. 休眠当前线程


Thread 类是 JVM 用来管理线程的一个类 , 换句话说 , 每个线程都有唯一的 Thread类 与之关联.Thread 类的对象就是用来描述一个执行流的 , JVM 会将这些Thread对象组织起来 , 用于线程调度和线程管理.


 1.Thread 的常见构造方法

方法说明
Thread()创建线程对象
Thread(Runnable target)使用 Runnable 对象创建线程对象
Thread(String name)创建线程对象 , 并命名
Thread(Runnable target , String name)使用Runnable 对象创建线程对象 , 并命名
Thread(ThreadGroup group , Runnable target)

线程可以被用来分组管理 ,

分好的组即为线程组 , 目前了解即可.

给线程创建的对象命名是为了方便在各种调试工具中调试. 

class MyRunnable implements Runnable{
    @Override
    public void run() {
        System.out.println("Hello Thread");
    }
}
public class ThreadDemo2 {
    public static void main(String[] args) {
        Thread t1 = new Thread();
        Thread t2 = new Thread("线程的名字");
        Thread t3 = new Thread(new MyRunnable());
        Thread t4 = new Thread(new MyRunnable() , "线程的名字");
    }
}

 2.Thread 的几个常见属性

属性获取方法
IDgetId()
名称getName()
状态getState()
优先级getPriority()
是否后台线程isDaemon()
是否存活isAlive()
是否被中断isInterrupted()
  • ID 是线程的唯一标识 , 不同线程不会重复.
  • 名称 在各种调试工具中用到.
  • 状态表示当前线程所处的一个情况.
  • 优先级高的线程 , 理论上来讲更容易被调度到.
  • 关于后台线程需要注意 , 后台线程的结束与否不会影响到进程.
  • 是否存活 , 通俗来讲就是 run() 是否结束了.
  • 关于是否中断 , 下面专门会讲.

3. 启动一个线程

之前我们以及知道 , 如何通过覆盖 run() 方法覆盖一个线程对象 , 但线程对象被创建出来并不意味着线程就开始运行了 .

  • 覆盖 run() 方法是提供给线程要做的事情的指令清单.
  • 创建线程对象可以认为是把张三 , 李四叫到一起.
  • 而调用 start() 方法才是喊了一声行动 , 线程才真正的执行起来.此时操作系统才会在底层创建一个线程.

 


 4. 中断一个线程

李四一旦进入工作状态 , 就会按照行动指南一直执行直到结束. 但有时出现突发状况 , 例如老板临时改变主意或者发现汇款对象是个骗子 , 这时就需要停止转账. 那么张三应该如何通知李四呢?这就涉及到中断线程的操作.

目前常见的有以下两种方式:

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

示例一: 通过共享标记为来沟通.

在主线程中就可以随时通过 flag 变量的取值 , 来操作 t 线程是否结束 , 但这种方式有一个明显的缺点就是不能及时响应 , 例如while循环中的休眠时间较长就需要一直等待.

public class ThreadDemo2 {
    public static boolean flag = true;
    public static void main(String[] args) {
        Thread t = new Thread(()->{
            while (true){
                System.out.println("Hello thread");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        });
        t.start();
        
        Thread.sleep(3000);
        //此时在主线程中就可以随时通过 flag 变量的取值 , 来操作 t 线程是否结束.
        flag = false;
    }
}

示例二: 调用 Interrupt() 方法来通知

currentThread() 是Thread类的静态方法 , 通过这个方法可以获取到当前线程 , 哪个线程调用这个方法哪个线程 , 就会得到哪个线程对象的引用.类似于 this. isInterrupted() 相当于上面例子中的标志位 , 为 true 表示终止 , 为 fasle 表示未被终止. t.interrupt() 就是终止线程.

Tips : 如果线程在 sleep 中休眠 , 此时调用 interrupt 就会出发 sleep 内部的异常(InterruptedException) , 导致sleep提前返回.

public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread(()->{
            while (!Thread.currentThread().isInterrupted()){
                System.out.println("Hello thread");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                     e.printStackTrace();;
                }
            }
        });
        t.start();
        Thread.sleep(3000);
        t.interrupt();
    }

此时运行代码就会发现问题 , 明明抛出异常但进程还在执行.

 这时因为 interrupt 虽然会做两件事:

  • 1. 把线程内部的标志位 boolean 给设置成 true.
  • 2. 如果线程在进行 sleep , 就会触发异常并且把 sleep 唤醒.

但 sleep 被唤醒后 , 还会做一件事 , 把刚才设置的这个标志位 , 再设置成 false .(清空标记为) 可以形象的理解成 sleep 有"起床气". 为了解决这一问题 , 可以在catch语句后加 break .线程立即响应你的请求. 为什么唤醒 sleep 后要清空标志位呢? 这时为了把唤醒 sleep 后程序是否要终止的选择权交给程序员自己.


5. 等待一个线程

由于线程的执行是一个随机调度的过程 , 等待线程要做事情就是更好的控制线程的执行顺序.

方法说明
public void join();等待线程结束
public void join(long millis);等待线程结束 , 最多等millis毫秒
public void join(long millis , int nanos);同理 , 精度更高.

主线程等待 t 线程彻底执行完后再继续执行. 

 public static void main(String[] args) {
        Thread t = new Thread(()->{
            System.out.println("Hello thread");
        });
        t.start();
        System.out.println("join 之前");
        //此处的 join 就是让当前的 main() 线程来等待 t 线程的执行结束(等待 t 的run() 执行完)
        try {
            t.join();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        System.out.println("join 之后");
    }

 

Tips: 如果开始执行 join 时 , t 已经结束了 , join将不会阻塞立即返回. 


6. 获取当前线程引用

方法说明
public static Thread currentThread();                                             返回当前线程对象的引用

 7. 休眠当前线程

方法说明
public static void sleep (long millis) throw InterruptedException休眠当前线程millis毫秒

线程休眠的本质是让这个线程不参与调度 , 在操作系统内核中 , 线程 A 调用 sleep , 线程 A 就会进入休眠状态 , 把 A 从就绪队列中取出放到阻塞队列中.


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

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

相关文章

机器学习基石2(noise和error)

文章目录一、什么是noise?二、什么是error?三、常用error一、什么是noise? 我们之前的讨论都是一种理想化的说明,比如数据来源于目标函数fff,似乎我们手里拿到的数据是这样得来的,随机取一个输入&#xff0…

DOM算法系列009-判断给定节点是否为块级元素

UID: 20221227215215 aliases: tags: source: cssclass: created: 2022-12-27 块级元素 给定一个节点,如何判定它是否为块级元素呢? 首先,块级元素一定是元素节点,所以它的nodeType 1其次,我们思考,有什…

Redis分布式缓存、秒杀

目录一、单点Redis的问题二、RDB三、AOF四、Redis优化秒杀流程1、秒杀步骤:2、Redis优化秒杀步骤:3、秒杀的lua脚本4、调用秒杀的lua脚本5、通过线程池,操作阻塞队列五、基于Redis实现共享session登录NoSQL数据库进阶实战哪吒精品系列文章一、…

linux常用命令(二)-文件操作

文件创建 - touch 一般使用touch 来创建某个新增的文件 语法 touch [-acfm][文件名]a:改变档案的读取时间记录c:假如目的档案不存在,不会建立新的档案。与 --no-create 的效果一样。f:不使用,是为了与其他 unix 系统…

python的tkinter(图形用户界面)

目录标题什么是图形用户界面(GUI)Tinter函数和参数说明(常用)Lable(标签):效果Button(按钮)效果Entry(文本框)效果Text (多行文本框)Canvas(画布)效果Message(消息弹窗)效果什么是图形用户界面&…

kaggle学习笔记-otto-baseline4-本地CV的构建

总览 步骤 1 - 生成候选 对于每个测试用户,我们生成可能的选择,即候选人。、我们从 5 个来源生成候选人: 点击、购物车、订单的用户历史记录测试周期间最受欢迎的 20 次点击、购物车、订单具有类型权重的点击/购物车/订单到购物车/订单的共…

中国芯片奇才,仅用三年打破欧美垄断,创造奇迹

有这么一位中国人,打破了欧美长达10年的芯片技术垄断。这位最该追的星,她是谁?又是如何让欧美芯片领域闻风丧胆。早在2017年,芯片国产化已接近50%,然而25g以上芯片却仅有3%,该技术一直掌握在欧美等发达国家…

融云任杰:激活组织生命力 让听见炮火的人做决策 | TGO专访

任杰,融云联合创始人兼首席科学家,TGO 鲲鹏会(北京)学员;曾就职于微软和神州泰岳等公司,在微软两次获得全球杰出员工奖,曾负责中国联通搭建 WAP 网关、增值业务管理平台;在神州泰岳期…

数据结构(线性表及顺序表)

目录 线性表 线性结构定义 常见线性结构 线性表 顺序表及其实现 顺序结构 顺序表的存储映像图 顺序表seqList及操作的定义(seqList.h) 顺序表基本操作的实现分析 查找操作 实现代码 插入操作 实现代码 删除操作 实现代码 顺序表应用——…

手绘图说电子元器件-集成电路

集成电路是高度集成化的电子器件,具有集成度高、功能完整、可靠性好、体积小、重量轻、功耗低的特点,已成为现代电子技术中不可或缺的核心器件。 集成电路可分为模拟集成电路和数字集成电路两大类,包括集成运放、时基集成电路、集成稳压器、门电路、触发器、计数器、译码器…

【 uniapp - 黑马优购 | 分类界面 】创建cate分支、数据获取、动态渲染

个人名片: 🐼作者简介:一名大二在校生,讨厌编程🎋 🐻‍❄️个人主页🥇:小新爱学习. 🐼个人WeChat:hmmwx53 🕊️系列专栏:&#x1f5bc…

【Lilishop商城】No4-4.业务逻辑的代码开发,涉及到:会员B端第三方登录的开发-web端第三方授权联合登录接口开发

仅涉及后端,全部目录看顶部专栏,代码、文档、接口路径在: 【Lilishop商城】记录一下B2B2C商城系统学习笔记~_清晨敲代码的博客-CSDN博客 全篇会结合业务介绍重点设计逻辑,其中重点包括接口类、业务类,具体的结合源代…

机器学习——支持向量机(SVM)

文章目录1. 优化目标2. 大间距的直观理解3. 大间距分类背后的数学支持向量机(Support Vector Machines)是广泛应用于工业界和学术界的一种监督学习算法,在学习复杂的非线性方程时提供了一种更为清晰,更加强大的方式。下面从SVM的优…

【nowcoder】笔试强训Day10

目录 一、选择题 二、编程题 2.1井字棋 2.2密码强度等级 一、选择题 1.下列运算符合法的是&#xff08; &#xff09; A. && B. <> C. if D. : 逻辑与&&语法规则&#xff1a;表达式1&&表达式2&#xff0c;其中两个表达式都是布尔表达式…

LeetCode453.最小操作次数使数组元素相等

LeetCode刷题记录 文章目录&#x1f4dc;题目描述&#x1f4a1;解题思路&#x1f4dc;题目描述 给你一个长度为 n 的整数数组&#xff0c;每次操作将会使 n - 1 个元素增加 1 。 返回让数组所有元素相等的最小操作次数。 示例1 输入&#xff1a;nums [1,2,3] 输出&#xff1a…

EduIQ Network LookOut Administrator

EduIQ Network LookOut Administrator 网络了望管理员允许您从屏幕的远端实时监视计算机。您可以随时看到他们在做什么。除了计算机控制&#xff0c;您还可以捕获摩西和键盘用户。使用Network LookOut Administrator软件可以完成一些有用的工作&#xff1a; 远程儿童计算机控制…

记录一次Gstreamer运行报错排查

背景 系统&#xff1a;Ubuntu 20.04 显卡型号&#xff1a;RTX 2060 之前正常运行的Gstreamer的编解码代码&#xff08;有用到显卡硬件加速&#xff09;&#xff0c;突然运行报错。经过一番折腾&#xff0c;最终找到原因&#xff0c;是因为NVIDIA驱动近期更新了&#xff0c;与…

Node.js——模块化(一)

1. 模块化的基本概念 1.1 什么是模块化 1. 编程领域中的模块化 1.2 模块化规范 2. Node.js 中的模块化 2.1 Node.js 中模块的分类 2.2 加载模块 加载自定义模块给相对路径 ./是平级&#xff08;同一文件夹下调用&#xff09; //这是07.test.js代码 // 注意&#xff1a;在使用…

Cypress笔记-连接命令

.each() 作用 遍历数组数据结构&#xff08;具有 length 属性的数组或对象&#xff09; cy.get(.connectors-each-ul>li).each(function($el, index, $list){ //遍历每个li元素console.log($el, index, $list)}).its() 作用 获取对象的属性值 示例代码 cy.get(.conne…

MergeTree概述

概述 Clickhouse 中最强大的表引擎当属 MergeTree &#xff08;合并树&#xff09;引擎及该系列&#xff08;MergeTree&#xff09;中的其他引擎。MergeTree 系列的引擎被设计用于插入极大量的数据到一张表当中&#xff0c;数据可以以数据片段的形式一个接着一个的快速写入&am…