你真的熟悉多线程的程序的编写?快来查漏补缺

news2025/1/21 0:52:08

目录

一、Thread 类的属性及常用的构造方法

1.1、 Thread 常见构造方法

1.2、Thread  类的常见属性

1.3、启动(创建)一个线程

1.4、中断一个线程

1.5、等待一个线程

1.6、休眠当前线程

1.7、当前线程让出的 CPU 资源

二、线程状态


一、Thread 类的属性及常用的构造方法


1.1、 Thread 常见构造方法

方法说明
Thread()创建线程对象
Thread(Runnable target)使用 Runnable 对象创建线程对象
Thread(String name)

创建线程对象,并命名(名字是可以重复的);

Thread(Runnable target, String name)使用 Runnable 对象创建线程对象,并命名
【了解】Thread(ThreadGroup group, Runnable target)线程可以被用来分组管理,分好的组即为线程组,这 个目前我们了解即可

Ps:创建线程的时候,给线程起个名字还是很有必要的,目的就是为了方便程序员调试,一旦出问题,方便找到对应的代码,如果不手动起名,JVM 默认会起名为 thread-0、thread-1......

1.2、Thread  类的常见属性

获取方法解释
getId()线程的 id,也是线程的唯一标识,不同线程不会重复
getName()名称,就是构造方法里给参数起的名字
getState()线程的状态(后面会细说)
getPriority()优先级,优先级高的线程理论上更容易被调度到
isDaemon()是否是“后台线程”,这里需要记住一点——如果是“前台线程”,那么当 main 运行完了,前台线程还没完,进程是不会退出的!如果是后台线程,那么当 main 等其他前台线程运行完了,即使后台线程没执行完,进程也会退出!
isAlive()判定内核线程还在不在,可以简单 理解为 run 方法执行完了,内核线程就销毁了。
isInterrupted()线程是否被中断
currentThread()返回当前线程对象的引用

1.3、启动(创建)一个线程

之前我们通过 new Thread 只是创建出了 Thread 对象,并没真正创建除线程!!!

Thread 对象虽然和内核中的线程是一一对应的,但是生命周期并非完全相同:Thread 对象创建出来了,内核中的线程还不一定有,调用 start 方法,内核的线程才创建出来当 run 运行完了,内核中的线程就销毁了,但是 Thread 对象还在。

Ps:直接调用 run 并不会创建线程,只是运行线程中的代码,调用 start 方法,才是创建了线程

1.4、中断一个线程

当 run 方法执行完了,线程就销毁了,那有没有办法让线程提前结束呢?

使用 thread 的 interrupt 方法就通知这个线程进行中断,这个线程具体如何处理,还需要看 run 里的逻辑是如何实现的,主要有以下几种情况:

  • thread 线程在运行状态,那么就设置标志 isInterrupted() 标志位为 true。 
  • thread 线程在阻塞状态(sleep),不会设置标志位,而是触发一个 InterruptedException  异常,这个异常会把 sleep 提前唤醒。

使用 interrupt 本质是让 run 方法尽快结束,而不是 run 执行一半强制结束!!!

最后,我们可以通过以下两种方法来看线程中断的标志位是否设置

标志位是否清除, 就类似于一个开关.

Thread.isInterrupted() 判断当前线程的中断标志是否被设置,清除中断标志(相当于按下开关, 开关自动弹起来了. 这个称为 "清除标志位")

Thread.currentThread().isInterrupted() 判断指定线程的中断标志是否被设置,不清除中断标志 (相当于按下开关之后, 开关弹不起来, 这个称为 "不清除标志位".)

a)例如使用 Thread.isInterrupted() 判断线程是否收到中断通知后,标志位会被清除. 如下:

    public static void main(String[] args) throws InterruptedException {

        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                for(int i = 0; i < 5; i++) {
                    System.out.println("当前线程是否收到中断的通知:" + Thread.interrupted());
                }
            }
        });
        thread.start();
        thread.interrupt();

    }

执行结果如下:

b) 使用 Thread.currentThread().isInterrupted() 判断线程是否收到中断通知后,标记位不会清除:

    public static void main(String[] args) throws InterruptedException {

        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                for(int i = 0; i < 5; i++) {
                    System.out.println("当前线程是否收到中断的通知:" + Thread.currentThread().isInterrupted());
                }
            }
        });
        thread.start();
        thread.interrupt();

    }

1.5、等待一个线程

线程之间的调度顺序是完全随机的,但我们也可以通过一些特殊的操作来对线程的执行顺序进行干预,其中 join 就是一个办法~

在 main 方法中调用 t1.join 的效果就是让main 线程阻塞等待,等到 t1 线程执行完了,main线程才继续执行,如下代码:

    public static void main(String[] args) throws InterruptedException {

        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                for(int i = 0; i < 5; i++) {
                    System.out.println("正在运行 t1 线程");
                }
            }
        });
        t1.start();
        t1.join();
        for(int i = 0; i < 5; i++) {
            System.out.println("正在运行 main 线程");
        }

    }

执行效果:

如果去掉 t1.join(),效果如下:

另外,join 还有一个带等待时间的版本,如下:

 也就是当超过了这个等待时间,就过时不候~

实际的开发中大多数都是指定了最大等待时间,避免程序“卡死”的情况~

1.6、休眠当前线程

sleep 指定休眠时间,可以让线程休息(阻塞)一会;

Thread 类下的静态方法说明
public static void sleep(long millis) throws InterruptedException

休眠当前线程 millis

毫秒

public static void sleep(long millis, int nanos) throws InterruptedException可以更高精度的休眠

Ps:因为线程的调度是不可控的,所以,这个方法只能保证实际休眠时间是大于等于参数设置的休眠时间的。

底层原理如下:

操作系统管理这些线程的 PCB 的时候,是有多个链表的,调用了sleep ,就会把 PCB 移动另外一个“阻塞队列”(原先在“就绪队列”),当 sleep 时间到了 ,就会被移动到之前的就绪队列。

Ps:移回了就绪队列,不代表立即就能在 CPU 上执行,还得看系统什么时候调用这个线程~

1.7、当前线程让出的 CPU 资源

通过 Thread.yield() 方法可以暂停当前正在执行的线程(让出当前的 CPU  资源),并执行其他线程。yield 做的就是让当前运行线程回到可运行的状态(就绪状态),以具有同样的优先级获得运行机会,也因此,实际中无法保证yield()达到让步目的,因为让步的线程还有可能被线程调度程序再次选中。

Ps:yield()从未导致线程转到等待/睡眠/阻塞状态。在大多数情况下,yield()将导致线程从运行状态转到可运行状态,但有可能没有效果。

二、线程状态


线程的状态是一个枚举类型 Thread.State。

不要被这个图吓到,他简化以后是这样的:

我们重点在于理解各个状态的意思:

  • NEW: Thread 对象创建出来了,但是内核中的线程还没有创建。
  • TERMINATED: 内核中的线程销毁了(线程的 run 方法执行完了),但是 Thread 对象还在。
  • RUNNABLE: 就绪状态(正在 CPU 上运行 + 在就绪队列中排队)。
  • TIMED_WAITING: 按照一定时间,进行阻塞(sleep)。
  • WAITING: 特殊的阻塞状态,调用 wait。
  • BLOCKED: 等待锁的时候进入阻塞状态。

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

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

相关文章

华为OD机试真题(Java),整数编码(100%通过+复盘思路)

一、题目描述 实现一个整数编码方法&#xff0c;使得待编码的数字越小&#xff0c;编码后所占用的字节数越小。 编码规则如下&#xff1a; 编码时7位一组&#xff0c;每个字节的低7位用于存储待编码数字的补码&#xff1b;字节的最高位表示后续是否还有字节&#xff0c;置1表…

2023联网公司时薪排行榜出炉,多多排榜首。微软、美团很强

今天分享一个对于选择公司非常有用的参考&#xff1a;“互联网时薪”。 我们在选择一个公司的时候&#xff0c;往往会比较关注总收入package (除了基本的月薪&#xff0c;加上其他的所有的收入&#xff0c;包括但不限于奖金、股票或股份的分红等等)。 然而&#xff0c;总收入…

算力网络安全

算力网络安全 1. 算力网络简介1.1 基本概念1.2 应用场景 2. 算力网络安全需求3. 算力网络安全架构3.1 算力网络参考架构3.2 资源层安全3.3 控制层和编排管理层安全3.4 服务层安全 4. 算力网络安全关键技术4.1 安全计算4.2 安全编排4.3 数据溯源4.4 可信内生4.5 操作审计4.6 安全…

【服务器】Linux搭建我的世界服务器 + 公网远程联机教程

Yan-英杰的主页 悟已往之不谏 知来者之可追 C程序员&#xff0c;2024届电子信息研究生 目录 前言 1. 安装JAVA 2. MCSManager安装 3.局域网访问MCSM 4.创建我的世界服务器 5.局域网联机测试 6.安装cpolar内网穿透 7. 配置公网访问地址 8.远程联机测试 9. 配置固定…

ICMP 协议详解

文章目录 1 概述2 ICMP 协议2.1 工作原理2.2 报文格式2.3 ICMP 类型 1 概述 #mermaid-svg-6yUB8ZNYSzjbbDDq {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-6yUB8ZNYSzjbbDDq .error-icon{fill:#552222;}#mermaid-s…

Qt 路径

Qt 路径 Qt中路径问题小结目录与路径的区别路径分隔符Qt 路径与 Windows 路径转换相对路径mkdir 和 mkpath判断目录是否存在修改路径setPath Qt中路径问题小结 原文链接&#xff1a;https://blog.csdn.net/Andy_93/article/details/52831175 在做Qt项目的时候&#xff0c;我们…

【重学c++primer】第二章 深入浅出:变量的类型

文章目录 【重学cprimer】第二章 变量以及变量的基本类型1、从初始化/赋值语句说起2、类型详解一些未定义部分字面值变量以及变量的类型隐式类型转换 3、复合类型&#xff1a;从指针到引用指针的操作void*指针的好处引用指针的引用 4、常量和常量表达式类型const和指针const的赋…

AndroidStudio导入Android AOSP源码

一、生成导入到AS所需的配置文件 1.1、切换到Android源码的目录&#xff0c;执行配置环境脚本 source build/envsetup.sh1.2、执行lunch,选择对应产品 lunch1.3、执行make idegen make idegen编译完成后&#xff0c;就可以在Android源码的根目录下看到android.iml和android…

元宇宙展厅--音乐科技展厅

作为音乐科技领域的先锋&#xff0c;这里是一个展示最新音乐科技的创新空间。我们的元宇宙展厅汇聚了来自世界各地最前沿的音乐创新&#xff0c;将展示最新、具有前瞻性的音乐科技应用。让您可以深入了解这个领域的最新发展。 一、音乐科技展厅概述 让我们来了解一下我们的元宇…

首期smardaten无代码训练营圆满收官,两周内容精彩回顾!

”smardaten无代码训练营&#xff0c;旨在通过线上碎片化时间的课程学习实操演练&#xff0c;帮助学员探索产品能力&#xff0c;验证项目需求&#xff0c;实现多个demo系统的复刻搭建。“ 首期smardaten无代码训练营于上周圆满收官&#xff01;本期共有64名学员报名参加&#…

KDZR-10A三相直流电阻测试仪

一、产品概述 直流电阻的测量仪是变压器、互感器、电抗器、电磁操作机构等感性线圈制造中半成品、成品出厂试验、安装、交接试验及电力部门预防性试验的项目&#xff0c;能有效发现感性线圈的选材、焊接、连接部位松动、缺股、断线等制造缺陷和运行后存在的隐患。 为了满足感…

Hive ---- DDL(Data Definition Language)数据定义

Hive ---- DDL&#xff08;Data Definition Language&#xff09;数据定义 1. 数据库&#xff08;database&#xff09;1. 创建数据库2. 查询数据库3. 修改数据库4. 删除数据库5. 切换当前数据库 2. 表&#xff08;table&#xff09;1. 创建表2. 查看表3. 修改表4. 删除表5. 清…

07_阻塞队列(BlockingQueue)

目录 1. 什么是BlockingQueue 2. 认识BlockingQueue 3. 代码演示 栈与队列概念 栈(Stack)&#xff1a;先进后出&#xff0c;后进先出 队列&#xff1a;先进先出 1. 什么是BlockingQueue 在多线程领域&#xff1a;所谓阻塞&#xff0c;在某些情况下会挂起线程&#xff08;即…

JVM 基本知识

目录 前言 一、JVM 内存区域划分 1.1 程序计数器 1.2 栈 1.3 堆 1.4 方法区 二、 JVM 类加载机制 2.1 类加载需要经过的几个步骤 2.1.1 Loading - 加载 2.1.2 Linking - 连接 2.1.3 initialization&#xff08;初始化&#xff09; 小结 经典面试题 三、JVM 垃圾…

天河新一代,安装OpenCV

1&#xff09;下载 Releases opencv/opencv GitHub 下载一个版本&#xff0c;传上去。 解压&#xff0c;因为只要最基本的功能&#xff0c;所以不需要ctri等包。 2&#xff09; 一些选项 cmake .. -D<选项名1><设定值1> -D<选项名2><设定值2> …

Metasploit Framework-安全漏洞检测工具使用

一款开源的安全漏洞检测工具&#xff0c;简称MSF。可以收集信息、探测系统漏洞、执行漏洞利用测试等&#xff0c;为渗透测试、攻击编码和漏洞研究提供了一个可靠平台。 集成数千个漏洞利用、辅助测试模块&#xff0c;并保持持续更新。 由著名黑客、安全专家H.D. Moore主导开发…

Hadoop学习笔记(二)环境配置与服务器克隆

VMware与Centos7的安装 这部分很简单&#xff0c;只需要按照常规步骤一步一步安装即可。最后出现如下画面便完成了。 如果出现了一打开 “开启虚拟机” 就蓝屏的情况。可以试试将VMware更新到16的版本以上。 对虚拟机进行一系列的设置 设置VMware的IP地址 接下来点击 “NAT设…

计算任意时间内课时出现次数以及冲突情况判断

背景 整体由四部分组成&#xff0c;报名时间、报名周期、上课时间、上课周期 通过选择报名时间、报名周期、以及上课时间&#xff0c;去计算在培训周期内总的培训课时&#xff0c;并当上课时间冲突时&#xff0c;给出提示。 需求&#xff1a; 报名时间&#xff08;日期时分&…

分享10个非常好用的绘图工具

无论你是一个专业的插画师&#xff0c;还是一个有创造力的人&#xff0c;想要随时记录生活的灵感&#xff0c;现在你只需要拿起平板电脑或打开电脑浏览器来描述你脑海中的图片。在本文中&#xff0c;我们选择了10个强大、方便、易于使用的在线绘图软件&#xff0c;其中一个必须…

人工智能之配置环境教程一:安装VsCode和Anaconda

人工智能之配置环境教程一&#xff1a;安装VsCode和Anaconda 作者介绍一&#xff0e; 安装VScode编辑器二. 安装Anaconda 作者介绍 孟莉苹&#xff0c;女&#xff0c;西安工程大学电子信息学院&#xff0c;2021级硕士研究生&#xff0c;张宏伟人工智能课题组。 研究方向&#…