多线程(二) ~ 线程核心属性与状态

文章目录

  • 一. 线程创建(start)
    • (一)继承Thread类,重写run
    • (二)继承Runnable类,重写run
    • (三)Thread匿名内部类重写
    • (四)Runnable匿名内部类重写
    • (五)lambda表达式
  • 二. 线程的关键属性
    • (一)线程名称
    • (二)线程是否为后台线程
      • 1. 前台线程
      • 2. 后台线程
      • 3. 查看是否是后台线程(isDaemon)
      • 4. 设置后台线程(setDaemon)代码及效果图
    • (三)线程是否存活
      • 1. 是否存活isAlive
      • 2. 代码及效果图
  • 三. 线程终止(interrupt)
    • (一)Java提供的API
      • 1. 用法
      • 2. 代码及效果图
    • (二)手动设置条件
      • 1. 用法
      • 2. 代码及其效果图
  • 四. 线程等待(join)
    • (一)定义
    • (二)代码及其效果图
  • 五. 获取线程引用(currentThread)
    • (一)用法
    • (二)代码及其效果图
  • 六. 线程休眠(sleep)
    • (一)定义
    • (二)代码
  • 七. 线程状态
    • (一)NEW
      • 1. 定义
      • 2. 代码及其效果图
    • (二)TERMINATED
      • 1. 定义
      • 2. 代码及其效果图
    • (三)RUNNABLE
      • 1. 定义
      • 2. 代码及其效果图
    • (四)TIMED_WAITING
      • 1. 定义
      • 2. 代码及其效果图
    • (五)WAITING
      • 1. 定义
      • 2. 代码及其效果图
    • (六)BLOCKED&LOCK
      • (①)
      • (②)
      • (③)

一. 线程创建(start)

(一)继承Thread类,重写run

class MyThread extends Thread {@Overridepublic void run() {while (true) {System.out.println("Thread!!!");try {Thread.sleep(100);} catch (InterruptedException e) {throw new RuntimeException(e);}}}
}public class demo1 {public static void main(String[] args) throws InterruptedException {Thread thread = new MyThread();thread.start();while (true) {System.out.println("main!!!");Thread.sleep(100);}}
}

(二)继承Runnable类,重写run

class MyRunnable implements Runnable {@Overridepublic void run() {while (true) {System.out.println("Thread!");}}
}public class demo2 {public static void main(String[] args) {MyRunnable runnable = new MyRunnable();Thread thread = new Thread(runnable);thread.start();while (true) {System.out.println("main!");}}
}

(三)Thread匿名内部类重写

package demo_thread;/*** Created with IntelliJ IDEA.* Description:* User: 32309* Date: 2025-07-11* Time: 20:06*/
public class demo3 {public static void main(String[] args) throws InterruptedException {Thread thread = new Thread() {@Overridepublic void run() {while (true) {System.out.println("Thread~~");try {Thread.sleep(0);} catch (InterruptedException e) {throw new RuntimeException(e);}}}};thread.start();while (true) {System.out.println("main~~");Thread.sleep(0);}}
}

(四)Runnable匿名内部类重写

package demo_thread;/*** Created with IntelliJ IDEA.* Description:* User: 32309* Date: 2025-07-11* Time: 20:14*/
public class demo4 {public static void main(String[] args) throws InterruptedException {Runnable runnable = new Runnable() {@Overridepublic void run() {while (true) {System.out.println("thread~");try {Thread.sleep(100);} catch (InterruptedException e) {throw new RuntimeException(e);}}}};Thread thread = new Thread(runnable);thread.start();while (true) {System.out.println("main~");Thread.sleep(100);}}
}

(五)lambda表达式

public class demo5 {public static void main(String[] args) throws InterruptedException {Thread thread = new Thread(() -> {while (true) {System.out.println("thread!");try {Thread.sleep(10);} catch (InterruptedException e) {throw new RuntimeException(e);}}},"阿然");thread.start();while (true) {System.out.println("main!");Thread.sleep(10);}}
}

二. 线程的关键属性

(一)线程名称

线程名字,我们可以通过setName方法来设置线程的名字,方便后期调试
通过getName方法可以获取线程名称
在这里插入图片描述

(二)线程是否为后台线程

1. 前台线程

当前台线程还在运行时,即使其他所有线程都运行完,进程也不停止,要等待前台线程结束,进程才结束

2. 后台线程

当所有前台线程运行完毕时,即使后台线程还有任务没有完成,也会终止进程

3. 查看是否是后台线程(isDaemon)

是否是后台线程通过isDeamon方法来查看
Java中线程创建时默认是前台线程

4. 设置后台线程(setDaemon)代码及效果图

public class demo7 {public static void main(String[] args) throws InterruptedException {Thread thread = new Thread(() -> {while (true) {System.out.println("thread~~~");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}},"thread");thread.setDaemon(true);thread.start();System.out.println(thread.isDaemon());for (int i = 0; i < 1   ; i++) {System.out.println("main");Thread.sleep(1000);}}
}

在这里插入图片描述

(三)线程是否存活

1. 是否存活isAlive

Java中Thread对象与CPU内核中的线程是一一对应的,但是有可能出现内核的线程已经摧毁了,而Thread对象还存在的情况
可以使用isAlive方法来查看线程是否存活

2. 代码及效果图

package demo_thread;/*** Created with IntelliJ IDEA.* Description:* User: 32309* Date: 2025-07-11* Time: 20:38*/
public class demo8 {public static void main(String[] args) throws InterruptedException {Thread thread = new Thread(() -> {for (int i = 0; i < 3; i++) {System.out.println("thread!");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}});thread.start();while (true) {System.out.println(thread.isAlive());Thread.sleep(1000);}}
}

在这里插入图片描述

三. 线程终止(interrupt)

(一)Java提供的API

1. 用法

1.Java中提供了控制线程结束的方法interrupted与isInterrupted
2. isInterrupted默认是false,在循环中取反使用来运行线程任务
3. 调用interrupt让isInterrupted置为true
4. 需要注意的是sleep休眠函数会使isInterrupted再次置为false

2. 代码及效果图

package demo_thread;/*** Created with IntelliJ IDEA.* Description:* User: 32309* Date: 2025-07-11* Time: 20:52*/
public class demo10_interrupt {public static void main(String[] args) throws InterruptedException {Thread thread = new Thread(() -> {while (!Thread.currentThread().isInterrupted()) {System.out.println(Thread.currentThread().getName());try {Thread.sleep(1000);} catch (InterruptedException e) {//throw new RuntimeException(e);break;}}System.out.println("进程结束");},"thread");thread.start();Thread.sleep(3000);System.out.println("main尝试终止");thread.interrupt();}
}

(二)手动设置条件

1. 用法

1. 手动设置循环关闭条件时,布尔条件需要是成员变量
2. 如果是局部变量那么布尔条件则不能改变,这样达不到关闭循环从而关闭线程的效果
3. 这是因为每次线程调度切换回该线程时,会从重新栈当中调取变量,如果局部变量则存在销毁可能,无法调取

2. 代码及其效果图

package demo_thread;/*** Created with IntelliJ IDEA.* Description:* User: 32309* Date: 2025-07-11* Time: 20:47*/
public class demo9 {private static boolean isFinish = false;public static void main(String[] args) throws InterruptedException {Thread thread = new Thread(() -> {while (!isFinish) {System.out.println("thread~~~");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}System.out.println("进程结束");},"thread");thread.start();for (int i = 0; i < 3; i++) {Thread.sleep(1000);}System.out.println("尝试终止进程翁");isFinish = true;}
}

在这里插入图片描述

四. 线程等待(join)

(一)定义

1.Java中线程等待函数时join
2. 线程1调用join,线程1就是被等待的线程,要等到线程1结束后才能结束进程
3. join可以设置等待时间,在设定的等待时间结束后,不论线程1是否完成任务,都不再等待,结束进程
4. join会抛出一个InterruptedException异常

(二)代码及其效果图

package demo_thread;/*** Created with IntelliJ IDEA.* Description:* User: 32309* Date: 2025-07-12* Time: 20:08*/
public class demo11_join {public static void main(String[] args) throws InterruptedException {Thread thread = new Thread(() -> {for (int i = 0; i < 3; i++) {System.out.println("thread ~");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}System.out.println("thread 线程结束!");});thread.start();thread.join(4000);System.out.println("main 线程结束!");}
}

在这里插入图片描述

五. 获取线程引用(currentThread)

(一)用法

  1. Java中Thread封装了获取当前线程的API,即currentThread方法
  2. currentThread方法是静态方法,可以直接用类名Thread调用

(二)代码及其效果图

package demo_thread;/*** Created with IntelliJ IDEA.* Description:* User: 32309* Date: 2025-07-13* Time: 21:46*/
public class demo_currentThread {public static void main(String[] args) {Thread main = Thread.currentThread();Thread thread = new Thread(() -> {for (int i = 0; i < 3; i++) {System.out.println("thread@");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}System.out.println("thread 线程结束");});thread.start();for (int i = 0; i < 5; i++) {System.out.println("main@");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}System.out.println("main 结束");}
}

在这里插入图片描述

六. 线程休眠(sleep)

(一)定义

1 Java中休眠方法是sleep
2. sleep方法是静态方法,可以直接用Thread调用
3. 调用sleep方法会抛出InterruptedException异常

(二)代码

                try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}

七. 线程状态

(一)NEW

1. 定义

线程还未创建的状态,没调用start

2. 代码及其效果图

package demo_thread;/*** Created with IntelliJ IDEA.* Description:* User: 32309* Date: 2025-07-12* Time: 20:18*/
public class demo12_new {public static void main(String[] args) {Thread thread = new Thread();System.out.println(thread.getState());}
}

在这里插入图片描述

(二)TERMINATED

1. 定义

线程终止状态,运行完毕已经结束

2. 代码及其效果图

package demo_thread;/*** Created with IntelliJ IDEA.* Description:* User: 32309* Date: 2025-07-12* Time: 20:21*/
public class demo13_TERMINATED {public static void main(String[] args) throws InterruptedException {Thread thread = new Thread(() -> {for (int i = 0; i < 3; i++) {}});thread.start();while (true) {System.out.println(thread.getState());Thread.sleep(1000);}}
}

在这里插入图片描述

(三)RUNNABLE

1. 定义

线程正在运行时状态

2. 代码及其效果图

package demo_thread;/*** Created with IntelliJ IDEA.* Description:* User: 32309* Date: 2025-07-12* Time: 20:28*/
public class demo14_RUNNABLE {public static void main(String[] args) {Thread thread = new Thread(() -> {while (true) {}});thread.start();System.out.println(thread.getState());}
}

在这里插入图片描述

(四)TIMED_WAITING

1. 定义

有时间限制的等待的线程状态

2. 代码及其效果图

package demo_thread;/*** Created with IntelliJ IDEA.* Description:* User: 32309* Date: 2025-07-12* Time: 20:34*/
public class demo15_TINE_WAITING {public static void main(String[] args) throws InterruptedException {Thread thread = new Thread(() -> {while (true) {try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}});thread.start();thread.join(1000*10000);}
}

在这里插入图片描述

(五)WAITING

1. 定义

没有时间限制的等待的线程状态

2. 代码及其效果图

package demo_thread;/*** Created with IntelliJ IDEA.* Description:* User: 32309* Date: 2025-07-12* Time: 20:39*/
public class demo16_WAITING {public static void main(String[] args) throws InterruptedException {Thread thread = new Thread(() -> {while (true) {}});thread.start();thread.join();}
}

在这里插入图片描述

(六)BLOCKED&LOCK

阻塞,这里我们只讨论的是加锁后阻塞,提到锁,不得不谈到死锁,有三种情况:
①:一个线程同时加锁两次
②:两个线程两把锁,一个线程获取到一把锁之后,再尝试获取另一把锁时,加锁形成循环,那么就会形成死锁!
③:N个线程M把锁,每个线程运转都需要用到两把锁的时候,就会形成循环,造成死锁阻塞

(①)

观察下方实例,我们可以发现,用 synchronized 的时候对一个线程多次加锁,不会触发阻塞,这说明 synchronized 是可重入锁!

在这里插入图片描述

package test;/*** Created with IntelliJ IDEA.* Description:* User: ran* Date: 2025-07-31* Time: 9:53* 一个线程多次加锁*/
public class test1 {public static void main(String[] args) {Object lock = new Object();Thread thread1 = new Thread(() ->{synchronized (lock) {synchronized (lock) {System.out.println("多次加锁!!!");}}   });thread1.start();}
}

(②)

观察下面的实例可以看出,线程1lock1 加锁后休眠1s, 再尝试对第二个 lock2 加锁时,会产生阻塞, 这是因为 线程2 已经对 lock2 加锁成功, 又尝试获取 lock1 的时候产生了阻塞, 导致 lock2 没有解锁, 所以 线程1 尝试获取 lock2失败, 产生阻塞, 相互循环, 形成死锁
在这里插入图片描述

package test;/*** Created with IntelliJ IDEA.* Description:* User: ran* Date: 2025-07-31* Time: 10:26*/
public class test2 {public static void main(String[] args) {Object lock1 = new Object();Object lock2 = new Object();Thread thread1 = new Thread(() -> {synchronized (lock1) {System.out.println("获取第一把锁: lock1");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}synchronized (lock2) {System.out.println("尝试获取第二把锁: lock2");}}});Thread thread2 = new Thread(() -> {synchronized (lock2) {System.out.println("获取第一把锁: lock2");synchronized (lock1) {System.out.println("尝试获取第二把锁: lock1");}}});thread1.start();thread2.start();}
}

(③)

通过下方实例,我们可以看出, N个对象M把锁, 当每个人都要嵌套两把锁才能工作时,就会形成阻塞
在这里插入图片描述

package test;/*** Created with IntelliJ IDEA.* Description:* User: ran* Date: 2025-07-31* Time: 10:54*/
public class test3 {public static void main(String[] args) {Object lock1 = new Object();Object lock2 = new Object();Object lock3 = new Object();Thread thread1 = new Thread(() -> {synchronized (lock1) {System.out.println("获取第一把锁: lock1");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}synchronized (lock2) {System.out.println("尝试获取第二把锁: lock2");}}});Thread thread2 = new Thread(() -> {synchronized (lock2) {System.out.println("获取第一把锁: lock2");synchronized (lock3) {System.out.println("尝试获取第二把锁: lock3");}}});Thread thread3 = new Thread(() -> {synchronized (lock3) {System.out.println("获取第一把锁: lock3");synchronized (lock1) {System.out.println("尝试获取第二把锁: lock1");}}});thread1.start();thread2.start();thread3.start();}
}

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

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

相关文章

Linux---编辑器vim

一、vim的基本概念1.三种模式①命令模式控制屏幕光标的移动&#xff0c;字符、字或行的删除&#xff0c;移动复制某区段及进入插入模式或者进去底行模式②插入模式可进行文本输入&#xff0c;按Esc回到命令行模式③底行模式文件保存或退出&#xff0c;也可以进行文件替换&#…

如何在 Ubuntu 24.04 或 22.04 LTS Linux 上安装 Guake 终端应用程序

通过本教程的简单步骤,在 Ubuntu 24.04 或 22.04 LTS Jammy JellyFish 上安装 Guake 终端以运行命令。 Guake(基于 Quake)是一个基于 Python 的终端模拟器。Guake 的行为类似于 Quake 中的终端:通过某个按键(热键)按下时,窗口会从屏幕顶部滚下来,再次按下相同的按键时…

谷歌Gemini 2.5重磅应用:多模态研究助手Multi-Modal Researcher,实现全网自动研究与AI播客生成

在人工智能赋能科研与内容创作的浪潮中,谷歌基于其最新大模型 Gemini 2.5 推出了突破性工具 Multi-Modal Researcher。这一系统通过整合多模态数据(文本、视频、实时网络信息),实现了从自动研究到内容生成的全流程自动化。用户只需输入研究主题或YouTube视频链接,系统即可…

防御综合实验

一、实验拓补图二、实验需求及配置需求一设备接口VLAN接口类型SW2GE0/0/2VLAN 10AccessGE0/0/3VLAN 20AccessGE0/0/1VLAN List : 10 20Trunk[SW2]vlan 10 [SW2]vlan 20 [SW2]interface GigabitEthernet 0/0/2 [SW2-GigabitEthernet0/0/2]port link-type access [SW2-GigabitEt…

堆----2.前 K 个高频元素

347. 前 K 个高频元素 - 力扣&#xff08;LeetCode&#xff09; /** 桶排序: 首先遍历数组,使用HashMap统计每个元素出现的次数 创建一个大小为length 1的List数组,下标代表元素出现次数,出现次数一致的元素放在同一个数组中 倒数遍历List数组即可得得到前K个高频元素 细节注…

如何分析Linux内存性能问题

一、Linux中的buffer与cache的区别 Linux的内存管理与监控_linux服务器虚假内存和真实内存怎么区分-CSDN博客文章浏览阅读66次。本文主要是关于【Linux系统的物理内存与虚拟内存讲解】【重点对虚拟内存的作用与用法进行了讲解说明】【最后还对如何新增扩展、优化、删除内存交换…

二次型 线性代数

知识结构总览首先是我们的二次型的定义&#xff0c;就是说什么样的才算是一个二次型。然后就是如何把二次型化为标准型&#xff0c;最后就是正定二次型的定义和判断的一些条件。二次型的定义二次型其实是一种函数表达的方式&#xff0c;如上&#xff0c;含义其实就是每个项都是…

云原生三剑客:Kubernetes + Docker + Spring Cloud 实战指南与深度整合

在当今微服务架构主导的时代&#xff0c;容器化、编排与服务治理已成为构建弹性、可扩展应用的核心支柱。本文将深入探讨如何将 Docker&#xff08;容器化基石&#xff09;、Kubernetes&#xff08;编排引擎&#xff09;与 Spring Cloud&#xff08;微服务框架&#xff09; 无缝…

vue让elementUI和elementPlus标签内属性支持rem单位

vue让elementUI和elementPlus标签内属性支持rem单位 如 Element Plus 的 el-table 默认不直接支持使用 rem 作为列宽单位 解决方法: 将 rem 转换为像素值&#xff08;基于根元素字体大小&#xff09; // 计算rem对应的像素值 const calcRem (remValue) > {// 获取根元素(ht…

基于OAuth2与JWT的微服务API安全实战经验分享

引言 在微服务架构中&#xff0c;API 安全成为了保护服务免受未授权访问和攻击的关键要素。本文结合真实生产环境案例&#xff0c;以实战经验为出发点&#xff0c;分享基于 OAuth2 JWT 的微服务 API 安全方案&#xff0c;从业务场景、技术选型、实现细节、踩坑及解决方案&…

scrapy库进阶一

scrapy 库复习 scrapy的概念&#xff1a;Scrapy是一个为了爬取网站数据&#xff0c;提取结构性数据而编写的应用框架 scrapy框架的运行流程以及数据传递过程&#xff1a; 爬虫中起始的url构造成request对象–>爬虫中间件–>引擎–>调度器调度器把request–>引擎…

Objective-C实现iOS平台微信步数修改指南

本文还有配套的精品资源&#xff0c;点击获取 简介&#xff1a;本文介绍如何在iOS平台上使用Objective-C语言&#xff0c;通过苹果的HealthKit框架读取和修改微信步数以及相关健康数据。首先介绍如何引入和使用HealthKit框架&#xff0c;包括请求权限、读取步数数据、写入步…

【ElementPlus】深入探索ElementPlus:前端界面的全能组件库

&#x1f4da; 引言在现代 Web 开发中&#xff0c;创建既美观又功能强大的用户界面是一项挑战。Element Plus&#xff0c;作为 Vue 3 生态中的明星 UI 组件库&#xff0c;以其丰富的组件、优秀的性能和易用性赢得了广大开发者的青睐。本文将全面覆盖 Element Plus 的 常用核心组…

Json Jsoncpp

文章目录Json 介绍Jsoncpp 介绍Json::Value序列化接口反序列化接口序列化操作反序列化操作Json 介绍 JSON&#xff08;JavaScript Object Notation&#xff0c;JavaScript 对象表示法&#xff09;是一种轻量级的数据交换格式&#xff0c;具有简洁、易读、跨平台等特点&#xff…

openwrt下安装istore(基于pve)

openwrt下安装istore&#xff08;基于pve&#xff09;ssh连接到openwrt&#xff0c;用如下命令安装istore&#xff1a;opkg update || exit 1cd /tmpwget https://github.com/linkease/openwrt-app-actions/raw/main/applications/luci-app-systools/root/usr/share/systools/i…

2025年Python Web框架之争:Django、Flask还是FastAPI,谁将主宰未来?

文章概要 作为一名Python开发者&#xff0c;我经常被问到同一个问题&#xff1a;在2025年&#xff0c;Django、Flask和FastAPI哪个框架更值得使用&#xff1f;随着技术的快速发展&#xff0c;这个问题的答案也在不断变化。本文将全面比较这三个主流Python Web框架的特点、性能、…

高级11-Java日志管理:使用Log4j与SLF4J

在现代Java应用开发中&#xff0c;日志&#xff08;Logging&#xff09;是系统监控、调试、故障排查和性能分析的核心工具。一个高效、灵活、可配置的日志系统&#xff0c;不仅能帮助开发者快速定位问题&#xff0c;还能为运维团队提供宝贵的运行时信息。在Java生态系统中&…

sc-atac的基础知识(0)

sc-atac的基础知识 **fragment**是ATAC-seq实验中的一个重要概念&#xff0c;它指的是通过Tn5转座酶对DNA分子进行酶切&#xff0c;然后经由双端测序得到的序列。根据Tn5插入导致的偏移从read比对得到的位置推断出fragment的起始和结束位置。根据之前的报道&#xff0c;Tn5转座…

Python从入门到精通计划Day01: Python开发环境搭建指南:从零开始打造你的“数字厨房“

目录一、配置你的「魔杖」&#xff1a;Python 3.x安装1.1 跨平台安装指南1.2 验证你的「法力值」二、选择你的「魔法工坊」&#xff1a;IDE配置2.1 VS Code&#xff1a;轻量级实验室2.2 PyCharm&#xff1a;专业级法师塔三、施展第一个「魔咒」&#xff1a;Hello World3.1 基础…

MCP Agent 工程框架Dify初探

目录引言一、Dify是什么二、为什么使用Dify三、使用Dify要怎么做1、聊天助手2、Agent2.1 Function calling&#xff08;函数调用&#xff09;和 ReAct 两种推理模式的区别2.1.1 技术本质与工作流程对比2.1.2 优缺点对比2.1.3 适用场景与选择依据2.2 LangChain 的 Agent 实现原理…