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

Java多线程——Thread类的基本用法

一.线程的创建

  1. 继承Thread类

//继承Thread类class MyThread extends Thread{@Overridepublic void run() {System.out.println("线程运行的代码");}
}
public class Demo1 {public static void main(String[] args) {MyThread t = new MyThread();t.start();//启动线程,此时被创建System.out.println("main执行的方法");}}
  1. 实现Runnab接口

//实现Runnab接口
class MyRunnable implements Runnable{@Overridepublic void run() {System.out.println("这是线程执行的代码");}
}
public class Demo2 {public static void main(String[] args) {Thread t = new Thread(new MyRunnable());t.start();System.out.println("这是main执行的代码");}}
  1. 匿名内部类创建Thread子类对象

public class Demo3 {public static void main(String[] args) {Thread t = new Thread(){@Overridepublic void run() {System.out.println("这是线程执行的代码");}};t.start();System.out.println("这是main执行的方法");}
}
  1. 匿名内部类创建Runnable接口

public class Demo4 {public static void main(String[] args) {Thread t = new Thread(new Runnable() {@Overridepublic void run() {System.out.println("这是线程执行的代码");}});t.start();System.out.println("这是main执行的代码");}}
  1. lambda表达式创建Runnab子类对象

public class Demo5 {public static void main(String[] args) {Thread t = new Thread(() -> {System.out.println("这是线程执行代码");});t.start();System.out.println("这是main执行代码");}
}

二.获取当前线程的实例

public static Thread currentThread()

返回当前对象的引用

 public static void main(String[] args) {Thread t = new Thread(() -> {Thread thread = Thread.currentThread();System.out.println(thread.getName());},"t线程");t.start();}
执行结果:
t线程

三.线程中断

  1. 使用自定义的标志位中断线程

public class Demo7 {public static boolean isQuit = false;//设置自定义标志位public static void main(String[] args) {Thread t = new Thread(() ->{while (!isQuit){System.out.println("线程代码");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}});t.start();try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}isQuit = true; //设置标志位System.out.println("标志位设置,线程执行结束");}
}

代码运行结果

线程代码
线程代码
标志位设置,线程执行结束
  1. 使用Thread.interrupted()或者Thread.currentThread().isInterrupted()代替自定义标志位

方法

说明

public void interrut()

中断对象关联的线程,如果该线程阻塞,则异常通知,否则设置标志位

public static boolean interrupted()

判断当前线程中断标志位是否设置,调用后清除标志位

public boolean isinterrupted()

判断对象关联的线程的标志位是否设置,调用后不清除标志位

使用示例

使用Thread.interrupted()作为中断标志位

    public static void main(String[] args) {Thread t = new Thread(() -> {while (!Thread.interrupted()){System.out.println("线程执行");}});t.start();try {Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}t.interrupt(); //设置中断标志位}
}

使用Thread.currentThread().isInterrupted()

   public static void main(String[] args) {Thread t = new Thread(() -> {while (!Thread.currentThread().isInterrupted()){System.out.println("线程执行");}});t.start();try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}t.interrupt(); //设置中断标志位}
}

Thread.currentThread().isInterrupted()与Thread.interrupted()的区别

Thread.interrupted()调用后,清除标志位

Thread.currentThread().isInterrupted()调用后,保留标志位

  public static void main(String[] args) {Thread t = new Thread(() -> {for (int i = 0; i < 3; i++) {System.out.println(Thread.interrupted());}});t.start();t.interrupt();}
执行结果
true
false
false
    public static void main(String[] args) {Thread t = new Thread(() -> {for (int i = 0; i < 3; i++) {System.out.println(Thread.currentThread().isInterrupted());}});t.start();t.interrupt();}
执行结果
true
true
true

注意

当线程因为调用wait/join/sleep等方法阻塞时,会以InterruptedException的异常通知,并且清除中断标志位,是否需要结束线程,取决catch中的写法,加上break结束线程,或者直接忽略继续向下执行

 public static void main(String[] args) {Thread t = new Thread(() -> {while (!Thread.currentThread().isInterrupted()){System.out.println("线程执行");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}});t.start();try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}t.interrupt(); //设置中断标志位}
执行结果:
线程执行
线程执行
线程执行
java.lang.InterruptedException: sleep interruptedat java.lang.Thread.sleep(Native Method)at Demo8.lambda$main$0(Demo8.java:14)at java.lang.Thread.run(Thread.java:748)
线程执行
线程执行
线程执行

四.线程等待

public void join()

等待线程结束

public void join(毫秒)

等待线程结束,最多等毫秒,超过时间不等待

线程1在main中调用join,目的是让main等待线程1结束再继续执行

未调用join 
public static void main(String[] args) {Thread t1 = new Thread(() -> {for (int i = 0; i < 2; i++) {System.out.println("线程1执行");}});t1.start();System.out.println("线程1执行完了");}
执行结果:
线程1执行完了
线程1执行
线程1执行调用joinpublic static void main(String[] args) {Thread t1 = new Thread(() -> {for (int i = 0; i < 2; i++) {System.out.println("线程1执行");}});t1.start();try {t1.join();} catch (InterruptedException e) {e.printStackTrace();}System.out.println("线程1执行完了");}
执行结果:
线程1执行
线程1执行
线程1执行完了

五.线程休眠

public static void sleep(毫秒)

Thread类方法,休眠当前线程,会抛异常,因为线程调度不可控,所以实际休眠时间接近设置的时间

 public static void main(String[] args)  {Thread t1 = new Thread(() -> {for (int i = 0; i < 3; i++) {System.out.println("线程执行");try {Thread.sleep(1000);System.out.println("休眠1s");} catch (InterruptedException e) {e.printStackTrace();}}});t1.start();}
执行结果:
线程执行
休眠1s
线程执行
休眠1s
线程执行
休眠1s

相关文章:

Java多线程——Thread类的基本用法

一.线程的创建继承Thread类//继承Thread类class MyThread extends Thread{Overridepublic void run() {System.out.println("线程运行的代码");} } public class Demo1 {public static void main(String[] args) {MyThread t new MyThread();t.start();//启动线程&a…...

【C++】类和对象练习——日期类的实现

文章目录前言1. 日期的合法性判断2. 日期天数&#xff08;/&#xff09;2.1 和的重载2.2 对于两者复用的讨论3. 前置和后置重载4. 日期-天数&#xff08;-/-&#xff09;5. 前置- -和后置- -的重载6. 日期-日期7. 流插入<<重载8. 流提取>>重载9. 总结10. 源码展示前…...

[LeetCode周赛复盘] 第 333 场周赛20230219

[LeetCode周赛复盘] 第 333 场周赛20230219 一、本周周赛总结二、 [Easy] 6362. 合并两个二维数组 - 求和法1. 题目描述2. 思路分析3. 代码实现三、[Medium] 6365. 将整数减少到零需要的最少操作数1. 题目描述2. 思路分析3. 代码实现四、[Medium] 6364. 无平方子集计数1. 题目描…...

数字化时代,如何做好用户体验与应用性能管理

引言 随着数字化时代的到来&#xff0c;各个行业的应用系统从传统私有化部署逐渐转向公有云、行业云、微服务&#xff0c;这种变迁给运维部门和应用部门均带来了较大的挑战。基于当前企业 IT 运维均为多部门负责&#xff0c;且使用多种运维工具&#xff0c;因此&#xff0c;当…...

Python爬虫(7)selenium3种弹窗定位后点击操作,解决点击登录被隐藏iframe无法点击的登陆问题

之前的文章有关于更多操作方式详细解答&#xff0c;本篇基于前面的知识点进行操作&#xff0c;如果不了解可以先看之前的文章 Python爬虫&#xff08;1&#xff09;一次性搞定Selenium(新版)8种find_element元素定位方式 Python爬虫&#xff08;2&#xff09;-Selenium控制浏览…...

如何对项目健康度进行测量?评估项目健康状况

项目驱动变革&#xff0c;大部分公司逐步由运营驱动转变为项目驱动&#xff0c;带来更多重新和商业价值。对组织而言&#xff0c;从商业角度看&#xff0c;项目旨在推动组织从一个状态转到另一个状态&#xff0c;从而达成特定目标。项目的健康情况如何关乎项目和变革的成本&…...

美国原装二手keysight E4980A(安捷伦)2MHZ LCR表

Agilent E4980A、Keysight E4980A、LCR 表&#xff0c;20 Hz - 2 MHz E4980A 是 Agilent 的 2 MHz LCR 表。LCR表是一种电子测试设备&#xff0c;用于测量电子元件的电感&#xff08;L&#xff09;、电容&#xff08;C&#xff09;和电阻&#xff08;R&#xff09;。LCR 表可…...

《clean coder》:关于摆烂,争论和心态

“凡是不能在五分钟之内解决的争论&#xff0c;都不能依靠辩论解决” ---- Kent Beck 作为一个码农&#xff0c;我并不是一个喜欢争论的角色。很长一段时间会陷入一种摆烂的&#xff0c;被动的状态。“既然其他人想要这么做&#xff0c;就这么办吧”。这可能是非专业的行为中最…...

jenkins下载与简单使用

1.jenkins下载 因为我仍然使用的是jdk1.8进行开发&#xff0c;所以我下载的是jenkins2.332.1版本&#xff08;jenkins2.346.1版本在2022年末不再支持java8&#xff0c;如果项目使用的是jdk11可以继续使用该jenkins版本&#xff09;&#xff0c;更多版本下载请点击jenkins下载 …...

3|物联网控制|计算机控制-刘川来胡乃平版|第3章:计算机总线技术 补充串行总线部分|课堂笔记|ppt

2022年 10月 10日 3.3 外部总线 3.3.2 RS-232-C总线 机械特性...

Blazor入门100天 : 身份验证和授权 (3) - DB改Sqlite

目录 建立默认带身份验证 Blazor 程序角色/组件/特性/过程逻辑DB 改 Sqlite将自定义字段添加到用户表脚手架拉取IDS文件,本地化资源freesql 生成实体类,freesql 管理ids数据表初始化 Roles,freesql 外键 > 导航属性完善 freesql 和 bb 特性 本节源码 https://github.com/…...

阅读源码和查看官方文档,是解决问题最高效的办法。

作为一个工作8年的老程序员告诉你&#xff1a;阅读源码和查看官方文档&#xff0c;是解决问题最高效的办法。不信你来看&#xff0c;这个困扰了读者半天的问题我查了源码和文档后瞬间解决。 前言 上周五有位读者私信我一个问题&#xff0c;说困扰了他半天&#xff0c;研究了一…...

云原生流量管理系统中 Service , Ingress 和 Endpoint 的关系

摘要 Kubernetes(简称 K8s)是一个用于容器编排和管理的开源平台,其中流量管理是 K8s 的重要功能之一。K8s 提供了多种流量管理方式,以便对不同场景下的流量进行控制和管理。以下是 K8s 中常用的流量管理系统: Service:Service 是 K8s 中最基本的流量管理方式,用于提供…...

给你安利几款好用的谷歌浏览器插件

给你安利几款好用的谷歌浏览器插件前言一 Octotree 插件二 GitCodeTree 插件三 SourceGraph 插件四 GitZip 插件五 Enhanced GitHub 插件六 插件下载安装6.1 谷歌应用商店下载6.2 离线安装6.2.1 下载插件6.2.2 安装插件七 移除、启用、停用插件小结前言 GitHub是全球最大的代码…...

JDK定时器Timer原理

前言 前些时间想到利用redis实现延时队列&#xff0c;但是底层的定时器不止如何实现好些&#xff0c;故此研究了一下jdk的Timer。 Timer是一个用于执行定时任务的类&#xff0c;可以单次执行或按指定时间间隔循环执行&#xff08;直到主动cancel或线程被杀掉&#xff09;。Ti…...

vue3中使用swiper完整版教程

介绍 在 vue3 中使用 swiper, 实现轮播图的效果&#xff1b;如果组件样式等模块引入不当&#xff0c;很有可能导致&#xff0c;页面无效果&#xff1b;或者想要的箭头或者切换效果异常问题。具体使用方式如下所示&#xff1a; 使用方式 使用命令 npm install swiper 安装 sw…...

某个div的滚动条样式

.item-body,.chart2{/*滚动条整体样式*/&::-webkit-scrollbar {/*高宽分别对应横竖滚动条的尺寸*/width: 10px;height: 1px;}/*滚动条里面小方块*/&::-webkit-scrollbar-thumb {border-radius: 10px;-webkit-box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);background:…...

Spring Boot框架基础介绍

Spring Boot 是一款基于 Spring 框架的开源应用程序开发工具&#xff0c;它旨在简化 Spring 应用程序的配置和开发过程。Spring Boot 提供了一种简单的方式来创建可独立运行的、生产级别的应用程序&#xff0c;并在需要时进行部署。Spring Boot 在微服务架构和云计算环境下得到…...

Git - 在主分支上创建分支并提交代码

拉取最新代码 因为当前在 master 分支下&#xff0c;你必须拉取最新代码&#xff0c;保证当前代码与线上同步&#xff08;最新&#xff09;&#xff0c;执行以下命令&#xff1a; git pull origin master创建分支 目前我们在 master 主分支上&#xff0c;需要执行以下命令&…...

第三届无线通信AI大赛分享交流会暨颁奖典礼顺利举办,大赛圆满收官

2月16日&#xff0c;第三届无线通信AI大赛分享交流会暨颁奖典礼在北京顺利举行&#xff0c;宣告大赛圆满收官。 分享交流会暨颁奖典礼以线上线下结合的形式展开&#xff0c;邀请无线通信领域的多位专家、学者与「基于AI的信道估计与信道状态信息反馈联合设计」、「基于AI的高精…...

QMC5883L的驱动

简介 本篇文章的代码已经上传到了github上面&#xff0c;开源代码 作为一个电子罗盘模块&#xff0c;我们可以通过I2C从中获取偏航角yaw&#xff0c;相对于六轴陀螺仪的yaw&#xff0c;qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...

JVM垃圾回收机制全解析

Java虚拟机&#xff08;JVM&#xff09;中的垃圾收集器&#xff08;Garbage Collector&#xff0c;简称GC&#xff09;是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象&#xff0c;从而释放内存空间&#xff0c;避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...

linux 错误码总结

1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...

spring:实例工厂方法获取bean

spring处理使用静态工厂方法获取bean实例&#xff0c;也可以通过实例工厂方法获取bean实例。 实例工厂方法步骤如下&#xff1a; 定义实例工厂类&#xff08;Java代码&#xff09;&#xff0c;定义实例工厂&#xff08;xml&#xff09;&#xff0c;定义调用实例工厂&#xff…...

Neo4j 集群管理:原理、技术与最佳实践深度解析

Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...

NPOI操作EXCEL文件 ——CAD C# 二次开发

缺点:dll.版本容易加载错误。CAD加载插件时&#xff0c;没有加载所有类库。插件运行过程中用到某个类库&#xff0c;会从CAD的安装目录找&#xff0c;找不到就报错了。 【方案2】让CAD在加载过程中把类库加载到内存 【方案3】是发现缺少了哪个库&#xff0c;就用插件程序加载进…...

MyBatis中关于缓存的理解

MyBatis缓存 MyBatis系统当中默认定义两级缓存&#xff1a;一级缓存、二级缓存 默认情况下&#xff0c;只有一级缓存开启&#xff08;sqlSession级别的缓存&#xff09;二级缓存需要手动开启配置&#xff0c;需要局域namespace级别的缓存 一级缓存&#xff08;本地缓存&#…...

ThreadLocal 源码

ThreadLocal 源码 此类提供线程局部变量。这些变量不同于它们的普通对应物&#xff0c;因为每个访问一个线程局部变量的线程&#xff08;通过其 get 或 set 方法&#xff09;都有自己独立初始化的变量副本。ThreadLocal 实例通常是类中的私有静态字段&#xff0c;这些类希望将…...

HTTPS证书一年多少钱?

HTTPS证书作为保障网站数据传输安全的重要工具&#xff0c;成为众多网站运营者的必备选择。然而&#xff0c;面对市场上种类繁多的HTTPS证书&#xff0c;其一年费用究竟是多少&#xff0c;又受哪些因素影响呢&#xff1f; 首先&#xff0c;HTTPS证书通常在PinTrust这样的专业平…...

React父子组件通信:Props怎么用?如何从父组件向子组件传递数据?

系列回顾&#xff1a; 在上一篇《React核心概念&#xff1a;State是什么&#xff1f;》中&#xff0c;我们学习了如何使用useState让一个组件拥有自己的内部数据&#xff08;State&#xff09;&#xff0c;并通过一个计数器案例&#xff0c;实现了组件的自我更新。这很棒&#…...