Java线程详解

news2024/12/27 14:20:21

线程是CPU调度和分配的基本单位,是操作系统可以识别的最小执行和调度单位,每个线程都有自己特定的独立的内存区域,当然也与其他线程共享堆内存,文件队列以及其他内核资源,Java虚拟机允许一个应用拥有多个线程并发工作。

每个线程都有优先级,高优先级的线程会优先于低优先级的线程执行。当不特别指定线程优先级时,新创建的线程优先级与发起创建操作线程的优先级一致,对于守护线程创建的线程而言,其也会被视作守护线程

守护线程指的是专门为了服务其他线程而创建的线程,比如垃圾回收线程,就是最典型的守护线程,当所有非守护线程都执行完毕时(包括主线程),此时JVM退出,进而守护线程也就停止运行了。

守护线程中不能持有需要关闭的资源,如文件,数据库等,当JVM退出时,守护线程没有机会执行关闭操作,极有可能丢失数据。

对于JVM而言,所有非守护线程都执行完毕时,无论有没有守护线程在运行,虚拟机都会自动退出。

JVM自动退出的情况

  1. 调用Runtime类的exit方法并且安全管理器允许进行退出操作时
  2. 所有的非守护线程都执行完毕时

线程创建方式

在Java中,有两种手动创建线程方式:

  1. 继承Thread类
  2. 使用Runnable类(也可以使用FutureTask+Callable或Runnable,但本质仍是Runnable的实现方式,FutureTask的顶级父类是Runnable)

继承Thread示例代码如下:

// 继承Thread类,在run方法中实现需要运行在线程中的逻辑
class PrimeThread extends Thread {
         long minPrime;
         PrimeThread(long minPrime) {
             this.minPrime = minPrime;
         }

         public void run() {
             // compute primes larger than minPrime
              . . .
         }
 }

// 启动线程运行
PrimeThread p = new PrimeThread(143);
p.start();

使用Runnable示例代码如下:

// 实现runnable类
class PrimeRun implements Runnable {
         long minPrime;
         PrimeRun(long minPrime) {
             this.minPrime = minPrime;
         }

         public void run() {
             // compute primes larger than minPrime
              . . .
         }
}

//  启动线程运行
PrimeRun p = new PrimeRun(143);
new Thread(p).start();

这里说的是手动创建两种方式,意思是开发者直接接触到Thread对象,需要自主控制Thread的运行停止等,在java中也有一些自动创建线程的并发工具,比如线程池(ExecutorService)等

线程状态切换

1-4-1-1

如上图所示,线程主要有初始,可运行,运行,等待/阻塞,终止五种状态。当线程获取到CPU时间片切为可运行状态时,就会从可运行状态切入运行状态。线程运行中,如果遇到了同步锁时,等待获取资源则会切入阻塞状态,获取到资源后再从阻塞状态切入运行状态,超时等待状态和等待状态切入切出与此类似。

线程常见接口说明

接口名接口说明备注
start开始执行该线程,表示该线程从初始状态进入可运行状态,当分配到CPU时间片后,就会进入运行状态/
stop强制结束该线程执行,表示线程从运行状态进入终止状态,已弃用/
yield当前线程释放CPU时间片,由运行状态进入可运行状态,让系统重新选择线程执行,有可能继续执行,也有可能等待/
join在当前线程,调用其他线程的join方法,则当前线程阻塞,直到其他线程执行完后,该线程继续执行,可选择指定最长阻塞时间,单位毫秒/
interrupt标记线程中断状态,并不等于该线程停止运行。如果当前线程处于阻塞状态,执行interrupt方法会抛出异常,可以尝试在异常内跳出run方法执行以终止线程/
setDaemon设置当前线程是否是守护线程,true-守护线程,false-不是守护线程/
setPriority设置线程优先级,传入的值在1-10之间,数值越大,优先级越高,默认优先级为5/
sleepThread类的static方法,让调用线程进入休眠状态,当线程持锁时,sleep不会导致锁匙放,只会释放CPU资源,sleep状态的线程不可以被唤醒/
wait使线程进入等待状态,线程在等待状态时会释放所持有的monitor锁,处于wait状态的线程可以通过notify或者notifyAll唤醒/

!!!易错点

t为Thread对象,调用t.sleep()并不一定是让线程t进入休眠状态,是让执行t.sleep()这段代码的线程进入休眠状态,所有要让线程休眠,必须在该线程内部执行Thread.sleep()

停止线程的方式

一般情况下,我们可以通过如下方式停止线程:

  1. 使用标志位,在标志位为true时跳出执行以结束线程
  2. 使用interrupt方法,在run方法中判断中断状态结束线程执行
  3. 使用stop方法强制停止线程,不推荐

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

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

相关文章

AI绘画——Lora模型 小人书·连环画 xiaorenshu

目录 小人书连环画 使用说明: Instructions for v1.5: Instructions for v1.0: 下载地址 模型演示(多图预警) Night Sky YOZORA Model 模型 Lora模型xiaorenshu pastel-mix模型pastel-waifu-diffusion.vae模型Lora模型xiaorenshu 小人书…

JavaSE05|数组的定义与使用

文章目录 JavaSE05|**数组的定义与使用**1.数据基本概念**2.** **数组是引用类型****3.** **数组的应用场景** JavaSE05|数组的定义与使用 1.数据基本概念 定义:可以看成是相同类型元素的一个集合 1.1数组初始化 动态初始化:在创建数组时&#xff0c…

使用 Kubectl Patch 命令更新资源

Kubectl patch 命令允许用户对运行在 Kubernetes 集群中的资源进行局部更新。相较于我们经常使用的 kubectl apply 命令,kubectl patch 命令在更新时无需提供完整的资源文件,只需要提供要更新的内容即可。 Kubectl patch 支持以下 3 种 patch 类型&…

ROS学习第三十三节——Arbotix使用

https://download.csdn.net/download/qq_45685327/87718484 1.介绍 通过 URDF 结合 rviz 可以创建并显示机器人模型,不过,当前实现的只是静态模型,如何控制模型的运动呢?在此,可以调用 Arbotix 实现此功能。 Arboti…

第九章 桥接模式

文章目录 前言一、桥接模式(Bridge)-基本介绍完整代码Brand 手机接口,定义行为Vivo 实现 Brand 接口XiaoMi 实现 Brand 接口Phone 抽象桥接类FoldedPhone 实现桥接 (折叠样式手机)UpRightPhone 实现桥接(直立样式手机)…

干货 | 被抑郁情绪所困扰?来了解CBT吧!

Hello,大家好! 这里是 壹脑云科研圈 ,我是 喵君姐姐~ 我们的情绪就像是一组正弦波,有情绪很高涨的时刻,也会有情绪低落的瞬间,也会有情绪平稳的时候。 这种情绪上的变化非常正常,也正是因为这…

shell的变量功能

文章目录 shell的变量功能什么是变量?变量的可变性与方便性影响bash环境操作的变量脚本程序设计(shell script)的好帮手 变量的使用与设置:echo、变量设置规则、unset变量的使用(echo)变量设置的规定使用案例 环境变量的功能用env观察环境变量与常见环境…

数据结构(五)—— 栈与队列(2)

一、接上章 栈与队列的中等、困难题。 堆是一块动态内存 栈是先进后出的堆的一种方法 队列是一种先进先出的线性表 二、题 2.5 150 逆波兰表达式求值 很有意思的一道题,将中缀表达式 4 13 / 5,转化为后缀表达式之后:["4", &qu…

深入理解机器学习——过拟合(Overfitting)与欠拟合(Underfitting)

分类目录:《深入理解深度学习》总目录 机器学习的主要挑战是我们的算法必须能够在先前未观测的新输入上表现良好,而不只是在训练集上表现良好。在先前未观测到的输入上表现良好的能力被称为泛化(Generalization)。通常情况下&…

测试需求平台6-数据持久化与PyMySQL使用

✍此系列为整理分享已完结入门搭建《TPM提测平台》系列的迭代版,拥抱Vue3.0将前端框架替换成字节最新开源的arco.design,其中约60%重构和20%新增内容,定位为从 0-1手把手实现简单的测试平台开发教程,内容将囊括基础、扩展和实战&a…

信息安全技术 健康医疗数据安全指南 付下载地址

声明 本文是学习GB-T 39725-2020 信息安全技术 健康医疗数据安全指南. 而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 数据使用管理办法示例 第一章 总则 第一条 为规范数据使用流程,根据国家相关法律法规及相关规定,特制定本…

imgaug Augment Polygons 对标注图片和polygons的数据增强

对于本地化进行图像的增强,大家都是非常好操作的。但是,对于标注信息一起增强,还是稍微有一些难度的,麻烦很多。 我是遇到一个数据集非常少的任务,只有40张图。就直接标记了去训练,发现几乎不拟合&#xf…

这一篇搞定Spring

文章目录 一、引言1.1 原生web开发中存在哪些问题? 二、Spring框架2.1 概念2.2 访问与下载 三、Spring架构组成四、山寨版的Spring容器4.1准备工作4.2 山寨IOC容器4.3 配置文件告诉容器 管理哪些bean4.4 相关类4.5 测试 容器 五、构建Maven项目5.1 新建项目5.2 选择…

深度强化学习——AlphaGo实例讲解(5)

现在我们来分析AlphaGo这个实例,看看深度强化学习是怎么样用来玩围棋游戏的 AlphaGo的主要设计思路: 首先是训练,要分3步来做: 1、behavior cloning:这是一种模仿学习,alphaGo模仿人类玩家,从…

STM32平衡小车 pid简单学习

自动控制系统 自动控制系统可分为开环控制系统和闭环控制系统。 1、开环控制系统开环控制系统(open-loop control system)指被控对象的输出(被控制量)对控制器(controller)的输出没有影响。在这种控制系统中,不依赖将被控量反送回来以形成任何闭环回路。 2、闭环控…

c++入门(下)

C入门(下) 对于C的基础语法的讲解,由想要实现多次重复的函数,引出宏函数和inline的内联函数的对比,对于inline的讲解和运用,在后,C语言中的NULL和C中独特的nullptr的相比两者的比较&#xff0c…

kong(4):限流配置

Kong 提供了 Rate Limiting 插件,实现对请求的限流功能,避免过大的请求量过大,将后端服务打挂。 Rate Limiting 支持秒/分/小时/日/月/年多种时间维度的限流,并且可以组合使用。例如说:限制每秒最 多 100 次请求&…

Windows Server 2012R2 安装mysql 丢失VCRUNTIME140_1.dll------亲测

无去启动此程序,因为计算机中丢失VCRUNTIME140_1.dll。尝试重新安装该程序以解决此问题。 1.解决思路 说到底还是缺少底层的依赖,先下载依赖然后安装,最后安装vc。要不然vc是安装不成功。 下载安装--一下的插件 安装过程中需要重启一次电脑。 注意:必…

Android LoaderManager AsyncTaskLoader加载全部图片RecyclerView BigImageView呈现,Java(1)

Android LoaderManager AsyncTaskLoader加载全部图片RecyclerView BigImageView呈现&#xff0c;Java&#xff08;1&#xff09; 权限&#xff1a; <uses-permission android:name"android.permission.READ_EXTERNAL_STORAGE" /><uses-permission android:n…

VUE3子组件-业务代码优化

Vue3子组件 1.简介 Vue 3组件的主要优势之一就是它们可以帮助你将你的应用程序分解成可维护和可重用的部分。当你在应用程序中多次使用相同的代码时&#xff0c;你可以将它们抽象成一个组件&#xff0c;然后在应用程序中的多个地方使用该组件&#xff0c;而不必每次都编写相同…