JUC专题——Java并发基础

本文部分内容节选自《Java并发编程的艺术》

线程

现代操作系统调度的最小单元是 线程 , 也叫 轻量级进程 . 一个进程里可以创建多个线程, 线程拥有各自的计数器, 堆栈和局部变量, 并且能够访问共享的内存变量

线程优先级

现代操作系统使用时分的形式调度运行的线程, 操作系统会分出一个个时间片, 线程会分配到若干时间片, 当线程的时间片用完了就会发生线程调度, 并等待下次分配. 时间片多少决定了线程使用处理器资源的多少, 而线程优先级就是决定线程需要多或者少分配一些处理器资源的线程属性

在 Java 线程中, 通过整型成员变量 priority 控制优先级, 优先级的范围是 1~10, 线程构建时可以通过 setPriority() 方法来修改优先级, 默认的优先级为 5. 优先级高的线程分配时间片的数量要多于优先级低的线程.

设置优先级时, 对于频繁阻塞(休眠或 I/O操作) 的线程需要设置较高优先级, 对于偏重计算的线程需要设置较低的优先级, 确保处理器不会被独占.

在不同JVM和不同操作系统上, 线程规划会存在差异, 有的操作系统会忽视对线程优先级的设定

线程状态

Java 线程在生命周期中可能处于如下的6种状态. 在给定的任意时刻, 线程只能处于其中一个状态

名称说明
NEW线程被创建, 但是没有调用 start() 方法
RUNNABLE允许状态, Java 线程将操作系统中就绪和运行两种状态笼统地称为 “运行中”
BLOCKED阻塞状态, 表示线程被锁阻塞
WAITING等待状态, 表示线程进入等待状态, 进入该状态表示当前线程需要等待其他线程做出特定动作
TIME_WAITING超时等待, 该状态不同于WAITING, 它是可以在指定的时间自行返回的
TERMINATED终止状态, 线程已经执行完毕

线程创建之后, 调用 start() 方法开始运行, 执行 wait() 方法, 线程进入等待状态, 进入等待状态的线程需要依靠其他线程的通知才能回到运行状态, 而超时等待状态相当于在等待状态的基础上增加了超时限制, 也就是超时时间到达时会自动恢复到运行状态. 当线程调用同步方法时, 在没有获取到锁的情况下, 线程会进入阻塞状态. 线程在执行 Runnablerun() 方法之后会进入到终止状态

Daemon线程

Daemon线程是一种支持型线程, 因为它主要被用作程序中后台调度和支持性工作. 这意味着, 当一个JVM中不存在非Daemon线程时, JVM会退出

可以通过 ThreadThread.setDaemon(true) 将一个线程设置为 Daemon线程

必须在启动线程之前就设置好这个线程是否是Daemon线程, 不能在启动之后再设置, 否则会报错

启动和终止线程

构建线程

在运行线程之前要构造一个线程对象, 线程对象在构造时候需要提供线程所需要的属性, 如线程所属的线程组, 优先级, 是否为Daemon线程等信息

启动线程

线程对象在初始化完成之后, 调用 start() 方法就能启动线程.

中断

中断表示一个运行中的线程是否被其他线程进行了终端操作. 其他线程通过调用该线程的 interrupt() 方法对其进行中断操作

线程通过检查自身是否被中断来进行响应, 线程通过方法 inInterrupted() 来进行判断是否被中断, 也可以调用静态方法 Thread.interrupted() 对当前线程的中断标记位进行复位.

终止线程

中断操作是一种简便的线程间交互方式, 且这种交互方式最适合用来取消或停止任务. 除了中断以外, 还可以利用一个boolean变量来控制是否需要停止任务并终止该线程

线程间通信

volatile 和 synchronized

关键字 volatile 可以用来修饰字段, 告知程序任何对该变量的访问均需要从共享内存获取, 而对于它的改变必须刷新回到共享内存, 它能保证所有线程对变量访问的可见性

关键字 synchronized 可以修饰方法或者以同步块的形式来进行使用, 它主要保证多个线程在同一时刻只有一个线程处于方法或同步代码块中, 保证线程对变量访问的可见性和排他性

等待/通知机制

一个线程修改了一个对象的值, 而另一个线程感知到了变化, 然后进行相应的操作, 整个过程开始于一个线程, 而最终执行又是另一个线程.

Java 通过内置的 等待/通知 机制解决了这个问题

等待/通知机制是所有Java对象都具备的, 因为这些方法被定义在 java.lang.Object 内部

方法名称描述
notify()通知一个在对象上等待的线程, 使其从 wait() 方法返回, 返回的前提是该线程拿到了对象的锁
notifyAll()通知所有等待在该对象上的线程
wait()调用该方法的线程进入 WAITING 状态, 只有等待另外线程的通知或者被中断才会返回, 需要注意, 调用 wait() 方法之后, 会释放对象的锁
wait(long)超市等待一段时间, 这里的参数单位是毫秒
wait(long, int)对于超时时间更细粒度的控制, 可以精确到纳秒

等待/通知机制, 是指一个线程 A 调用了对象 O 的 wait() 方法进入等待状态, 而另一个对象 B 调用了对象 O 的 notify() 或者 notifyAll() 方法, 线程 A 收到通知后从对象 O 的 wait() 方法返回, 进而执行后续操作. 上述两个线程通过对象 O 完成交互, 而对象上的 wait()notify()/notifyAll() 就像是开关信号一样, 用来完成等待方和通知方之间的交互工作

使用 wait()notify() / notifyAll() 需要注意的细节

  1. 使用 wait() , notify()notifyAll() 时需要先对调用对象加锁
  2. 调用 wait() 方法后, 线程状态由 RUNNING 变为 WAITING, 并将当前线程放置到对象的等待队列
  3. notify()notifyAll() 方法调用之后, 等待线程仍然不会从 wait() 返回, 需要调用 notify()notifyAll() 的线程释放锁之后, 等待线程才有机会从 wait() 返回
  4. notify() 方法将等待队列中的一个等待线程从等待队列中移到同步队列中, 而 notifyAll() 方法则是将等待队列中所有的线程全部移到同步队列, 被移动的队列状态由 WAITING 变为 BLOCKED
  5. wait() 方法返回的前提是获得了调用对象的锁

管道输入/输出流

管道输入/输出流主要用于线程之间的数据传输, 而传输的媒介是内存

管道输入/输出流有四种实现: PipedOutputStream, PipedInputStream, PipedReader, PipedWriter, 前两种面向字节, 后两者面向字符

Thread.join() 的使用

如果一个线程 A 执行了 thread.join() 语句, 其含义是: 当前线程 A 等待thread线程终止之后才从 thread.join() 返回. 线程 Thread 除了提供 join() 方法之外, 还提供了 join(long millis)join(long millis, int nanos) 两个具备超时特性的方法. 这两个超时方法表示如果线程thread在给定的超时时间内没有终止, 那么将会从超时方法中返回

ThreadLocal 的使用

ThreadLocal, 即线程变量, 是一个以 ThreadLocal对象为键, 任意对象为值的存储结构, 这个结构被携带在线程上, 也就是说一个线程可以根据一个 ThreadLocal 对象查询到绑定在这个线程上的一个值

可以通过 set(T) 方法来设置一个值, 在当前线程下可以通过 get() 方法获取到原先设置的值

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

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

相关文章

lua 光速入门

文章目录 安装注释字符串变量逻辑运算条件判断循环函数Table (表)常用全局函数模块化 首先明确 lua 和 js Python一样是动态解释性语言,需要解释器执行。并且不同于 Python 的强类型与 js 的弱类型,它有点居中,倾向于强类型。 安装 下载解释…

【OpenHarmony】TDD-FUZZ环境配置

零、参考 1、AttributeError: ‘ElementTree‘ object has no attribute ‘getiterator‘:https://blog.csdn.net/suhao0911/article/details/110950742 一、创建工作目录 1、新建工作目录如:D:\0000_TDD_FUZZ\0000_ohos_tdd_fuzz。 2、gitee上下载 t…

陇剑杯 ios 流量分析 CTF writeup

陇剑杯 ios 流量分析 链接:https://pan.baidu.com/s/1KSSXOVNPC5hu_Mf60uKM2A?pwdhaek 提取码:haek目录结构 LearnCTF ├───LogAnalize │ ├───linux简单日志分析 │ │ linux-log_2.zip │ │ │ ├───misc日志分析 │ │…

html+vue编写分页功能

效果&#xff1a; html关键代码&#xff1a; <div class"ui-jqgrid-resize-mark" id"rs_mlist_table_C87E35BE"> </div><div class"list_component_pager ui-jqgrid-pager undefined" dir"ltr"><div id"pg…

Linux编辑器-vim的使用

vim的基本概念 vim的三种模式(其实有好多模式&#xff0c;目前掌握这3种即可),分别是命令模式&#xff08;command mode&#xff09;、插 入模式&#xff08;Insert mode&#xff09;和底行模式&#xff08;last line mode&#xff09;&#xff0c;各模式的功能区分如下&#…

中医优势病种诊疗方案数据库

中医诊疗方案结合了几千年的实践经验与理论体系&#xff0c;形成了一套独特的诊疗方法。随着国家对中医药事业的重视&#xff0c;多个中医诊疗方案被国家卫生健康委员会和国家中医药管理局等权威机构正式发布&#xff0c;这对规范中医临床诊疗行为&#xff0c;提升医疗服务质量…

执行npm命令一直出现sill idealTree buildDeps怎么办?

一、问题 今天在运行npm时候一直出项sill idealTree buildDeps问题 二、 解决 1、先删除用户界面下的npmrc文件&#xff08;注意一定是用户C:\Users\{账户}\下的.npmrc文件下不是nodejs里面&#xff09;&#xff0c;进入到对应目录下&#xff0c;Mac启动显示隐藏文件操作&…

生产服务器变卡怎么排查

服务器变卡怎么排查&#xff0c;可以从以下四个方面去考虑 生产服务器变卡怎么排查 1、网络2、cpu的利用率3、io效率4、内存瓶颈 1、网络 可以使用netstat、iftop等工具查看网络流量和网络连接情况&#xff0c;检查是否网络堵塞、丢包等问题 2、cpu的利用率 1、用top命令定…

驱动执行篇之电机编码器:编码器基础与双编码器方案

目录 |1.编码器概述 |2.编码器分类 |2.1.增量式编码器和绝对值编码器 |2.2.光电编码器 |3.双编码器方案 |3.1几种扭矩感知方案 |3.3双编码器安装方式 |1.编码器概述 编码器 编码器&#xff0c;是将信号&#xff08;如比特流&#xff09;或数据进行编制、转换为可用以通讯…

ECA-Net:深度卷积神经网络中的高效通道注意力机制【原理讲解及代码!!!】

ECA-Net&#xff1a;深度卷积神经网络中的高效通道注意力机制 在深度学习领域&#xff0c;特别是在深度卷积神经网络&#xff08;DCNN&#xff09;中&#xff0c;注意力机制已经成为提升模型性能的关键技术之一。其中&#xff0c;ECA模块&#xff08;Efficient Channel Attent…

前端项目的导入和启动

安装依赖 前端安装依赖只需要在控制台执行“npm i”即可。Tips&#xff1a;当我们执行的时候&#xff0c;有时候会很慢。可以考虑使用yarn或者pnpm。然而使用yarn或者pnpm有时候有一些莫名其妙的问题。所以还是得使用npm&#xff0c; 这个时候可以通过更换镜像源为淘宝镜像源。…

flex上下固定中间占固定高度(中间左右菜单)且内容自动滚动

效果图 布局&#xff1a; <view class"pop_tSet"><view class"pop_Con"><view class"box_bb"><view class"bb_title">{{titleObj[popType]}}</view></view><view class"box_bb_bot"…

The Sandbox 推出全新后室模板!

我们非常高兴地向你介绍游戏制作器的另一个新成员&#xff1a; 后室模板&#xff01; 步入神秘而不自然的空旷空间&#xff0c;感觉有些......不对劲。准备好探索、创造和拥抱引人入胜的后室世界吧。 什么是后室&#xff08;Backroom&#xff09;游戏&#xff1f; 早在 2019 年…

获取公募基金持仓【数据分析系列博文】

摘要 从指定网址获取公募基金持仓数据&#xff0c;快速解析并存储数据。 &#xff08;该博文针对自由学习者获取数据&#xff1b;而在投顾、基金、证券等公司&#xff0c;通常有Wind、聚源、通联等厂商采购的数据&#xff09; 1. 导入必要的库&#xff1a; pandas 用于数据处理…

Java中类装载的执行过程

类装载的执行过程 类从加载到虚拟机中开始&#xff0c;直到卸载为止&#xff0c;它的整个生命周期包括了&#xff1a;加载、验证、准备、解析、初始化、使用和卸载这7个阶段。其中&#xff0c;验证、准备和解析这三个部分统称为连接&#xff08;linking&#xff09;。 1.加载 …

第一天学C++(C++入门)

一、HelloWorld &#xff08;第一个C入门程序&#xff09; 1.1代码 #include<iostream> using namespace std; // 1.单行注释// 2. 多行注释 /* main 是一个程序的入口 每个程序都必须有这么一个函数 有且仅有一个 */ int main() {// 第九行代码的含义就是在屏幕中输出…

果园系统养殖游戏喂养偷菜种植浇水养成小程序

装扮 通过购买装扮场景切换不同的农场风格 土地升级 通过特定的材料对土地和房屋进行升级 日志 记录道具的使用数量及金币农作物的收入情况 幸运转盘 可用金币进行抽奖 宝箱开启 获得宝箱后可以通过金币开启 每日签到 每日签到获得奖励 系统公告 可以第一时间知道游戏的更新和…

【安全】查杀linux挖矿病毒 kswapd0

中毒现象 高cpu占用&#xff0c;使用top命令查看cpu使用率长时间50%以上&#xff0c;cpu占用异常的进程八成就是挖矿病毒进程 此病毒隐藏了自己&#xff0c;top命令无法查看到挖矿病毒进程&#xff0c;可通过sysdig命令找到隐藏进程 安装sysdig curl -s https://s3.amazonaw…

2024年软件开发行业的薪资水平在下滑的原因?

下降的原因主要包括&#xff1a; 科技行业竞争加剧&#xff1a;随着科技行业竞争的加剧&#xff0c;企业为了压缩成本&#xff0c;开始降低程序员的薪资水平。 人才供应过剩&#xff1a;在计算机成为热门学科的同时&#xff0c;社会上出现了对IT业泡沫和虚假繁荣的质疑。大量…

vue-textarea光标位置插入指定元素

vue-textarea光标位置插入指定元素 需求 点击插入关键字的时候把内容插入到光标所在的位置 效果图 实现 html <div class"temlate-container"><div class"template-content"><el-inputref"modelContent"v-model"mould.m…