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

Java线程

文章目录

  • 一、Thread类
    • 1.1创建线程
    • 1.2Thread类中的一些构造方法
    • 1.3Thread类中的一些属性
    • 1.4线程的终止/打断
    • 1.5线程等待
    • 1.6获取当前线程的引用
    • 1.7休眠当前线程
  • 二、线程的状态

一、Thread类

线程是操作系统的概念,操作系统内核实现了线程这样的机制,系统对外提供API,让用户可以通过API进行跟线程有关的编程。Java中的的Thread类对操作系统提供的API进行进一步的抽象和封装。

1.1创建线程

方法①:继承Thread,重写Thread中的run方法。
方法②:实现Runnable,重写Runnable中的run方法。
方法③:继承Thread,重写run,但是使用匿名内部类。
方法④:实现Runnable,重写run,但是使用匿名内部类。
方法⑤:lambda表达式创建线程(推荐写法),lambda本质上是一个匿名函数(没有名字的函数,只用一次),主要用来实现“回调函数”的效果。Java中不允许函数独立存在,在Java中的lambda本质是函数式接口(本质上还是没有脱离类)

Thread t = new Thread(() -> { });//{}中写重写的run方法的内容

1.2Thread类中的一些构造方法

Thread(String name)、Thread(Runnable target, String name)使创建线程的时候可以指定线程的名字,使得后续调试时用jdk中的jconsole.exe查看线程时根据线程名字更容易区分线程。

1.3Thread类中的一些属性

getId():线程的身份Id,这个Id是Java给线程分配的,不是系统api提供的线程Id也不是PCB中的Id

getName():获取线程名字

getState():获取线程状态

getPriority():虽然Java提供了api可以设置/获取进程的优先级,但是作用不大,因为在应用程序的角度很难察觉出优先级带来的差异,优先级影响到的是系统在微观上进行的调度

isDaemon():是否为守护线程/后台线程
后台线程:后台线程没有执行结束不影响整个进程的结束
前台线程:前台线程没有执行结束,此时整个进程一定不会结束
默认情况下线程是前台线程

isAlive():判断内核线程是否存在(“回调方法”执行完毕后内核线程就销毁了)
Thread对象的生命周期要比系统内核中的线程更长一些,所以可能出现Thread对象还在内核中的线程已经销毁了这种情况

1.4线程的终止/打断

Java中让线程终止的方法是让run()更快地执行完。
方法①:手动创建出标志位来作为run()的执行结束条件,比如下面的代码创建标志位为isQuit。

   private static boolean isQuit = false;//把isQuit设置为成员变量,此时lambda访问这个成员变量就不再是变量的捕获了,而是内部类中访问外部类的属性(lambda表达式是函数式接口相当于内部类),此时就没有final之类的限制了public static void main(String[] args) throws InterruptedException {Thread t = new Thread(() -> {while (!isQuit) {System.out.println("线程工作中");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}System.out.println("线程工作完毕!");});t.start();Thread.sleep(5000);isQuit = true;System.out.println("设置 isQuit 为 true");}

方法①有缺点:需要手动创建变量;当新线程内部已经进入循环在sleep()的时候,这时主线程再修改变量作为循环的终止条件,新线程完成循环后再结束新线程,即主线程完成修改后新线程不能及时响应结束。所以由此引入写法②。
方法②:用Thread类中现成的标志位终止线程,这里面用到了Thread类中的currentThread(),isInterrupted(),interrupt()。

    public static void main(String[] args) {Thread t = new Thread(() -> {// Thread 类内部, 有一个现成的标志位, 可以用来判定当前的循环是否要结束.while (!Thread.currentThread().isInterrupted()) {//Thread.currentThread()是获取当前线程的实例相当于t,哪个线程调用currentThread()就会返回哪个线程的对象,isInterrupted()用于判断Thread对象内部的标志位是否为trueSystem.out.println("线程工作中");try {Thread.sleep(1000);//正常来说sleep会休眠时间到了才能唤醒,但t.interrupt()可以使sleep内部触发出现一个异常,从而打破休眠,sleep抛出异常时会自动清除t.interrupt()设置为true的标志位,使标志位重新恢复为false。为什么这样设定?因为Java希望当线程收到要终止这样的信号的时候能够让我们自由决定接下来如何处理,就是让我们有更多的可操作空间,有可操作空间的前提是出现异常} catch (InterruptedException e) {// 1.不做处理,循环继续正常执行.e.printStackTrace();// 2. 加上一个 break, 表示让线程立即结束.// break;// 3. 做一些其他工作, 完成之后再结束.//其他工作的代码写在这里.break;}}});t.start();try {Thread.sleep(5000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("让 t 线程终止. ");t.interrupt();//把Thread对象中的标志位设置为true,即使线程内部的逻辑出现阻塞(如有sleep),使用这个方法也可以打破阻塞}

1.5线程等待

t是Thread类型的对象。
t.join()(哪个线程调用join哪个线程就去等待,哪个对象调用join哪个对象就被等)

t.join()工作过程:
①如果t线程正在运行中,此时“调用join()的线程”就会阻塞,一直阻塞到t线程执行结束为止
②如果t线程执行结束了,此时“调用join()的线程”就不会涉及到阻塞

还有join(long millis)//join的括号里写“超时时间”(最多等millis毫秒)
还有join(long millis, int nanos)//nanos是纳秒的意思,但这个纳秒意义不大。s、ms、us、ns是秒、毫秒、微秒、纳秒的意思。

1.6获取当前线程的引用

public static Thread currentThread();//哪个线程调用currentThread()就返回哪个线程对象的引用。

1.7休眠当前线程

public static void sleep(long millis) throws InterruptedException和public static void sleep(long millis, int nanos) throws InterruptedException//nanos是毫秒的意思,但这个毫秒的意义不大,因为比如sleep(1000)会存在一定精度误差。

系统会按照1000这个时间来让线程休眠,但是到达1000秒之后系统就会唤醒这个线程(线程从阻塞状态变为就绪状态),但不是这个线程变为就绪状态后就能立即回到cpu上运行,线程回到CPU上运行之前有一个系统调度的开销。

二、线程的状态

NEW:Thread对象已经有了,start方法还没调用

TERMINATE:Thread对象还在,内核中的线程已经销毁了

RUNNABLE:就绪状态(线程已经在cpu上执行/线程正在排队等待上cpu执行)

TIMED_WAITING:阻塞,由于sleep/join这种固定时间的方式产生的阻塞

WAITING:阻塞,由于wait这种不固定时间的方式产生的阻塞

BLOCKED:阻塞,由于锁竞争导致的阻塞

相关文章:

Java线程

文章目录 一、Thread类1.1创建线程1.2Thread类中的一些构造方法1.3Thread类中的一些属性1.4线程的终止/打断1.5线程等待1.6获取当前线程的引用1.7休眠当前线程 二、线程的状态 一、Thread类 线程是操作系统的概念,操作系统内核实现了线程这样的机制,系统…...

C语言如何实现DES加密与解密

C语言实现DES加密解密 #include "des.h" //移位表 static Table_size const shiftTable[NumberOfKeys] {1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1}; //E扩展表 static Table_size const eTable[des_key_pc2_standard]{32, 1, 2, 3, 4, 5, 4, 5, 6, …...

【笔记】优先队列(priority_queue/set)

目录 大根堆 小根堆 set(小根堆) 大根堆 题目链接:洛谷 P3243 菜肴制作 题目描述 知名美食家小 A 被邀请至 ATM 大酒店,为其品评菜肴。ATM 酒店为小 A 准备了 n 道菜肴,酒店按照为菜肴预估的质量从高到低给予 1 到…...

看看安森美深力科NSI45090JDT4G 是如何点亮汽车内外照明系统解决方案

关于线性恒流调节器(CCR):是一种用于控制电流的稳定输出。它通常由一个功率晶体管和一个参考电流源组成。CCR的工作原理是通过不断调节功率晶体管的导通时间来维持输出电流的恒定。当输出电流超过设定值时,CCR会减少功率晶体管的导…...

Linux进阶之Shell-sed

基本用法: sed 选项 “指令” 文件 常用选项: -e   --它告诉sed将下一个参数解释为一个sed指令,只有当命令行上给出多个sed指令时使用 -f   --后跟保存了sed指令的文件 -i   --直接对内容进行修改,不加 i 时默认只是预…...

前端高频面试题 Day02

面试题 var 和 let const 的区别 var 是 ES5 及之前的语法,let const 是 ES6 语法var 和 let 是变量,可修改;const 是常量,不可修改var 有变量提升,let const 没有var 没有块级作用域,let const 有 &…...

MYSQL完全卸载、安装与账号创建、权限控制

一、卸载mysql CentOS 卸载 MySQL 1. 查看安装情况 使用以下命令查看当前安装mysql情况,查找以前是否装有mysql rpm -qa|grep -i mysql这里显示我安装的 MySQL 服务有有: 2. 停止 mysql 服务、删除之前安装的 mysql 删除命令:rpm -e –n…...

get与post如何拼接url与数据的灵活处理,循环的重要性。

get与post拼接url地址不同: let postData {method: "post",data: {op: "/api/setting/maintenanceperiod?period"this.authorizationCode,loadingConfig: {},data: {period:this.authorizationCode}}}; if(this.editData.id){let postData …...

Remote Sensing,2023 | 基于SBL的分布式毫米波相干雷达成像的高效实现

Remote Sensing,2023 | 基于SBL的分布式毫米波相干雷达成像的高效实现 注1:本文系“无线感知论文速递”系列之一,致力于简洁清晰完整地介绍、解读无线感知领域最新的顶会/顶刊论文(包括但不限于 Nature/Science及其子刊; MobiCom, Sigcom, MobiSys, NSDI…...

Android学习之路(5) UI控件之Button (按钮)与 ImageButton (图像按钮)

本节引言: 今天给大家介绍的Android基本控件中的两个按钮控件,Button普通按钮和ImageButton图像按钮; 其实ImageButton和Button的用法基本类似,至于与图片相关的则和后面ImageView相同,所以本节 只对Button进行讲解&am…...

Day 31 C++ STL常用算法(下)

文章目录 常用拷贝和替换算法copy——容器内指定范围的元素拷贝到另一容器中函数原型注意——利用copy算法在拷贝时,目标容器要提前开辟空间示例 replace——将容器内指定范围的第一个旧元素修改为新元素函数原型注意——replace只会替换区间内满足条件的第一个旧元…...

【Android Studio】 win11 安装配置 jdk17 超详细

概述 一个好的安装教程能够帮助开发者完成更便捷、更快速的开发。书山有路勤为径,学海无涯苦作舟。我是秋知叶i、期望每一个阅读了我的文章的开发者都能够有所成长。 一、下载JDK JDK官网 这里下载 JDK17 windows x64 installer 二、安装JDK 双击打开下载的 j…...

IDEA下方工具栏SideBar没有Services解决方法 IDEA配合微服务学习多端口管理打开Services栏方法

问题 微服务学习时,一次要打开多个端口,比如8080给order模块、8081给user模块……这就需要用idea管理多端口。 这时候就可以用到Services栏进行管理。 解决 首先看下方Sidebar没有Services。 打开Services 打开方式一:手动打开 在IDEA中…...

[Vue warn]: Error in render: “SyntaxError: “undefined“ is not valid JSON“

[Vue warn]: Error in render: “SyntaxError: “undefined” is not valid JSON” 这说明出现了undefined这个变量类型,比如JSON.parse()时候会出现,可以先尝试打印JSON.parse()括号中的内容是否是undefined,如果是,那问题的根源…...

ui设计师工作总结及计划范文模板

ui设计师工作总结及计划范文模板【篇一】 白驹过隙,转眼间某某年已近结尾,时间伴随着我们的脚步急驰而去,到了个人工作总结的时候,蓦然回首,才发现过去的一年不还能画上圆满的句号,内心感慨万千&#xff0c…...

【Kafka】2.在SpringBoot中使用官方原生java版Kafka客户端

目 录 1. 新建一个消息生产者2. 新建一个消息消费者3. 测 试 在开始之前,需要先做点准备工作,用 IDEA 新建一个 Maven 项目,取名 kafka-study,然后删掉它的 src 目录,接着在 pom.xml 里面引入下面的依赖。这个项目的作…...

使用腾讯云轻量服务器Matomo应用模板建网站流量统计系统

腾讯云百科分享使用腾讯云轻量应用服务器Matomo应用模板搭建网站流量统计系统,Matomo 是一款开源的网站数据统计软件,可以用于跟踪、分析您的网站的流量,同时充分保障数据安全性、隐私性。该镜像基于 CentOS 7.6 64位操作系统,已预…...

clickhouse-监控配置

一、概述 监控是运维的一大利器,要想运维好clickhouse,首先就要对其进行监控,clickhouse有几种监控数据的方式,一种是系统本身监控,一种是通过exporter来监控,下面分别描述一下 二、系统自带监控 我下面会对监控做一…...

C++11并发与多线程笔记(5)互斥量概念、用法、死锁演示及解决详解

C11并发与多线程笔记(5)互斥量概念、用法、死锁演示及解决详解 1、互斥量(mutex)的基本概念2、互斥量的用法2.1 lock(),unlock()2.2 lock_guard类模板 3、死锁3.1 死锁演示3.2 死锁的一般解决方案:3.3 std:…...

华为云classroom赋能--Devstar使应用开发无需从零开始

华为云DevStar为开发者提供业界主流框架代码初始化能力,通过GUI、API、CLI等多种方式,将按模板生成框架代码的能力推送至用户桌面。同时基于华为云服务资源、成熟的DevOps开发工具链和面向多场景的众多开发模板,提供一站式创建代码仓、自动生…...

golang循环变量捕获问题​​

在 Go 语言中,当在循环中启动协程(goroutine)时,如果在协程闭包中直接引用循环变量,可能会遇到一个常见的陷阱 - ​​循环变量捕获问题​​。让我详细解释一下: 问题背景 看这个代码片段: fo…...

在rocky linux 9.5上在线安装 docker

前面是指南,后面是日志 sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo dnf install docker-ce docker-ce-cli containerd.io -y docker version sudo systemctl start docker sudo systemctl status docker …...

线程与协程

1. 线程与协程 1.1. “函数调用级别”的切换、上下文切换 1. 函数调用级别的切换 “函数调用级别的切换”是指:像函数调用/返回一样轻量地完成任务切换。 举例说明: 当你在程序中写一个函数调用: funcA() 然后 funcA 执行完后返回&…...

【Go】3、Go语言进阶与依赖管理

前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课,做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程,它的核心机制是 Goroutine 协程、Channel 通道,并基于CSP(Communicating Sequential Processes&#xff0…...

零基础在实践中学习网络安全-皮卡丘靶场(第九期-Unsafe Fileupload模块)(yakit方式)

本期内容并不是很难,相信大家会学的很愉快,当然对于有后端基础的朋友来说,本期内容更加容易了解,当然没有基础的也别担心,本期内容会详细解释有关内容 本期用到的软件:yakit(因为经过之前好多期…...

视觉slam十四讲实践部分记录——ch2、ch3

ch2 一、使用g++编译.cpp为可执行文件并运行(P30) g++ helloSLAM.cpp ./a.out运行 二、使用cmake编译 mkdir build cd build cmake .. makeCMakeCache.txt 文件仍然指向旧的目录。这表明在源代码目录中可能还存在旧的 CMakeCache.txt 文件,或者在构建过程中仍然引用了旧的路…...

基于 TAPD 进行项目管理

起因 自己写了个小工具,仓库用的Github。之前在用markdown进行需求管理,现在随着功能的增加,感觉有点难以管理了,所以用TAPD这个工具进行需求、Bug管理。 操作流程 注册 TAPD,需要提供一个企业名新建一个项目&#…...

面向无人机海岸带生态系统监测的语义分割基准数据集

描述:海岸带生态系统的监测是维护生态平衡和可持续发展的重要任务。语义分割技术在遥感影像中的应用为海岸带生态系统的精准监测提供了有效手段。然而,目前该领域仍面临一个挑战,即缺乏公开的专门面向海岸带生态系统的语义分割基准数据集。受…...

招商蛇口 | 执笔CID,启幕低密生活新境

作为中国城市生长的力量,招商蛇口以“美好生活承载者”为使命,深耕全球111座城市,以央企担当匠造时代理想人居。从深圳湾的开拓基因到西安高新CID的战略落子,招商蛇口始终与城市发展同频共振,以建筑诠释对土地与生活的…...

MySQL 索引底层结构揭秘:B-Tree 与 B+Tree 的区别与应用

文章目录 一、背景知识:什么是 B-Tree 和 BTree? B-Tree(平衡多路查找树) BTree(B-Tree 的变种) 二、结构对比:一张图看懂 三、为什么 MySQL InnoDB 选择 BTree? 1. 范围查询更快 2…...