【Java】Java核心要点总结70
文章目录
- 1. volatile 如何保证变量的可⻅性?
- 2. volatile 可以保证原⼦性么?
- 3. synchronized 关键字
- 4. synchronized 和 volatile 的区别
- 5. synchronized 和 ReentrantLock 的区别
1. volatile 如何保证变量的可⻅性?
在Java中,使用volatile关键字可以确保变量的可见性。
当一个线程修改了一个被volatile修饰的变量时,它会立即将该变量的最新值刷新到主内存。而其他线程在读取该变量时,会从主内存中重新获取最新值,而不是使用缓存中的旧值。
这样做的原因是,普通的变量在多线程环境下存在线程间不可见的问题。每个线程都有自己的工作内存,由于运行速度快和编译优化等原因,线程可能会直接读取工作内存中的旧值,而不去主内存中获取最新的值,导致线程之间的数据不一致。
而使用volatile修饰的变量会禁止线程对其进行缓存,并且强制线程在每次访问时从主内存中读取最新的值。这样可以确保变量的可见性,使得所有线程看到的值都是一致的。
需要注意的是,volatile只能保证可见性,并不能解决并发操作的原子性问题。如果涉及到需要确保原子性操作的场景,例如自增或自减操作,需要使用原子类(如AtomicInteger)或者利用锁来保证线程安全。
2. volatile 可以保证原⼦性么?
不,volatile关键字无法保证原子性。
volatile关键字只能确保变量的可见性,即线程在读取该变量时,能够获取到最新的值。它通过禁止线程对被修饰的变量进行缓存,强制从主内存中读取最新的值。
但是原子性是指一个操作是不可中断的,要么完全执行成功,要么完全不执行。volatile关键字不能保证复合操作的原子性,例如自增或自减操作。
如果需要保证操作的原子性,可以使用以下方式之一:
使用 synchronized 关键字来实现同步,确保在同一时间只有一个线程执行该代码块。
使用 Lock 或者 Atomic 类提供的原子操作类,例如 AtomicInteger、AtomicLong,它们提供了针对特定操作的原子性保证。
需要根据具体场景选择适合的解决方案,以保证正确的并发控制和数据一致性。
3. synchronized 关键字
synchronized 是 Java 中用于实现线程安全的关键字之一。它可以用来修饰方法或代码块,确保在同一时间只有一个线程执行被修饰的代码部分。
当一个线程进入一个被 synchronized 修饰的代码块或方法时,它会尝试获取对象锁(也称为监视器锁)。如果该对象的锁没有被其他线程持有,那么当前线程就获取到了锁,并开始执行代码;而其他线程则需要等待锁的释放。
通过使用 synchronized 关键字,可以实现以下两个主要目标:
互斥性:同一时间只有一个线程可以获得对象锁,执行被 synchronized 修饰的代码块或方法,从而避免多个线程同时访问共享资源导致的数据不一致或竞态条件问题。
可见性:当一个线程释放对象锁时,它会将对共享变量的修改刷新到主内存中,使得其他线程可以看到最新的值。这样可以保证数据的可见性,防止线程间的缓存不一致问题。
需要注意的是,synchronized 的互斥性依赖于获取的对象锁,因此不同线程必须使用相同对象的锁才能起到同步作用。另外,过度使用 synchronized 可能会导致性能问题,因此在设计并发程序时需要注意合理使用锁机制。
4. synchronized 和 volatile 的区别
volatile 和 synchronized 都是 Java 中用于处理并发编程的关键字,但它们有以下几个主要区别:
作用范围:
volatile 仅作用于变量,用于保证变量的可见性。
synchronized 既可以修饰方法,也可以修饰代码块,用于实现线程间的互斥和同步。
可见性:
volatile 关键字保证被修饰的变量对所有线程都是可见的,即当一个线程修改了该变量的值后,其他线程可以立即看到最新的值。
synchronized 关键字会在进入同步块(或方法)之前将工作内存中的数据刷新回主内存,并在退出同步块时强制刷新主内存中的数据到工作内存。这样可以保证共享变量的可见性。
原子性:
volatile 不能保证复合操作的原子性。例如,对一个 volatile 变量进行自增操作时,并不能确保该操作是原子的。
synchronized 可以保证同一时间只有一个线程执行被锁定的代码块,从而保证了代码块内部的操作是原子的。
锁机制:
volatile 并不涉及锁的获取与释放,它仅仅是保证被修饰的变量对所有线程的可见性。
synchronized 通过获取和释放对象锁来实现线程间的互斥和同步。在使用 synchronized 时,进入同步块之前需要先获得对象锁,而退出同步块时会释放该锁。
综上所述,volatile 关键字适用于简单的变量可见性问题,而 synchronized 关键字更强大,可以解决复杂的互斥和同步问题,并且提供了原子性的保证。根据具体的需求和场景选择合适的关键字。
5. synchronized 和 ReentrantLock 的区别
synchronized 和 ReentrantLock 都是 Java 中用于实现线程安全的机制,它们有以下几个主要区别:
可重入性:
synchronized 是可重入锁,也就是说同一个线程可以多次获得同一个锁。
ReentrantLock 也是可重入锁,并且提供了更灵活的使用方式,例如可以通过设置公平性来控制线程获取锁的顺序。
锁的获取与释放:
synchronized 关键字会自动获取和释放锁,在进入 synchronized 代码块或方法时获取锁,在退出时释放锁。
ReentrantLock 则需要手动调用 lock() 方法进行锁的获取,并在合适的时候调用 unlock() 方法释放锁。相比之下,这种方式更加灵活,但也容易忘记调用 unlock() 导致死锁。
等待可中断性:
ReentrantLock 提供了可中断的获取锁的方式,即在等待锁的过程中,可以响应中断请求。通过调用 lockInterruptibly() 方法,如果其他线程中断了当前线程,当前线程会立即抛出 InterruptedException 异常。
synchronized 关键字在获取锁时,如果锁被其他线程持有,那么当前线程会一直等待,无法响应中断。
可选择性:
ReentrantLock 可以根据需要选择公平锁和非公平锁。公平锁能够保证线程获取锁的顺序与请求的顺序一致,而非公平锁则允许插队,可能会导致某些线程长时间等待。
synchronized 关键字并不提供公平性的选择,它总是使用非公平锁。
性能:
在低竞争的情况下,synchronized 的性能通常比 ReentrantLock 好,因为 synchronized 由 JVM 内部实现,经过优化。
在高竞争或复杂的同步场景下,ReentrantLock 可能比 synchronized 更适用,因为它提供了更多的灵活性和可操作性。

相关文章:
【Java】Java核心要点总结70
文章目录 1. volatile 如何保证变量的可⻅性?2. volatile 可以保证原⼦性么?3. synchronized 关键字4. synchronized 和 volatile 的区别5. synchronized 和 ReentrantLock 的区别 1. volatile 如何保证变量的可⻅性? 在Java中,使…...
如何把一个 Git 仓库的分支加入另一个无关的 Git 仓库
文章目录 笔者需要将两个无关的 Git 仓库合并,也就是把一个 Git 仓库的分支加入另一个无关的 Git 仓库。笔者琢磨了一下之后就实现了。方法如下。 笔者的运行环境: git version 2.37.0.windows.1 TortoiseGit 2.11.0.0 IntelliJ IDEA 2023.1.1 (Ultima…...
深蓝学院C++基础与深度解析笔记 第 4 章 表达式
第 4 章 表达式 一、表达式基础 A、表达式: 由一到多个操作数组成,可以求值并 ( 通常会 ) 返回求值结果: #include <iostream> int main(){int x;x 3; }最基本的表达式:变量、字面值通常来说,表达式会包含操作符(运算符…...
CLION开发STM32之W5500系列(一)
开篇说明 本系列适用于需要使单片机通过网口进行通信的开发。针对的是刚入门的同学们,也是个人的经验分享。本次使用到的芯片为stm32f103vet6(其他的也可以)本次使用的网口模块为W5500,其网关有示例程序均可以参考.本次使用Clion+OpenOCD+ARM-GCC 进行开发、烧录、编译.建议熟…...
Web3通过ganache运行起一个本地虚拟区块链
通过文章 Web3开发准备工作 手把手带你创建自己的 MetaMask 账号大家简单的对网络 有了个比较模糊的概念 不同的网络连接这不同的区块链 那么 我们就要搞清楚 我们切换不同的网络 我们的数字资产是不一样的 在这里 我们需要先安装一个插件工具 ganache 我们先在本地创建一个文…...
01 背包问题解析与代码 python 实现
01 背包问题解析与代码 问题定义 给定一堆具有不同重量 { w 1 , w 2 , ⋯ , w n } \{ w_1,w_2, \cdots,w_n \} {w1,w2,⋯,wn}与价值 { v 1 , v 2 , ⋯ , v n } \{ v_1,v_2, \cdots,v_n \} {v1,v2,⋯,vn}的背包(knapsack),在总重…...
Vue实现前端视频展示列表及特征提取、笔记、删除、文件夹组织功能
Vue实现前端视频展示列表及特征提取、笔记、删除、文件夹组织功能 在前端展示上传的视频列表时,我们可以使用Element-UI中的Card组件来实现。同时,我们还可以添加一些功能,如缓存播放的视频、选择视频文本特征提取处理、写笔记、删除视频、组…...
多传感器时频信号处理:多通道非平稳数据的分析工具(Matlab代码实现)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...
数据结构算法 -分而治之算法
引言 坤坤是一个养鸡场的员工,他非常热爱他的工作,并且总是努力提高他的专业技能。有一天,养鸡场接到了一项任务:在短时间内处理一批大量的鸡。 这批鸡数量非常大,比普通的数量要多得多,坤坤意识到他们需…...
涉密信息系统口令管理制度
第一条 口令是涉密信息系统身份认证的基本防护措施,为保障 涉密信息系统的安全运行,规范网络用户及系统口令,特制定本制度。 第二条 具有口令功能的计算机、网络设备等计算机信息系统设 备,必须使用口令对用户的身份进行验证…...
UML与流程图
UML简介 UML(Unified Modeling Language,统一建模语言)是一种用于软件系统分析与设计的标准化建模语言。它提供了一套丰富的图形符号和规则,可用于描述系统的结构、行为和交互,帮助开发人员、设计师和利益相关者之间进…...
音视频开发Level0: 入门级20~25k的工作
今天给大家分享一个音视频开发领域,入门级别的工作,要求不高。 主要做什么呢,行车记录仪,运动相机,各种拍摄器材包括医疗领域的喉镜啊,等等。 这种产品,招人的公司深圳最多,因为深…...
Git第一章、Git的原理与使用
目录 一、Git安装 1.1Linux Centos安装 二、Git基本操作 2.1创建 Git 本地仓库 2.2配置Git 三、认识工作区、暂存区、版本库 3.1添加文件(场景一) 3.2修改文件 3.3版本回退 四、撤销修改 4.1情况一:对于工作区的代码,还…...
软件开发流程
目录 软件软件开发流程的演变 瀑布模型敏捷模型 XPSCRUMDevOps 1.软件 与计算机系统操作有关的计算机程序、可能有的文件、文档及数据。 软件可以分为两种主要类型: 独立软件:独立软件是一种完整的应用程序,可以直接在计算机或移动设备上…...
编程语言的优劣评选标准与未来发展趋势——探索最佳编程语言选择
编程语言的优劣评选标准与未来发展趋势——探索最佳编程语言选择 评判标准不同编程语言的优点与缺点分析对编程语言未来发展的猜测和未来趋势 💕 💕 💕 博主个人主页: 汴京城下君–野生程序员💕 💕 &#x…...
axios 发送请求请求头信息不包含Cookie信息
问题 axios 发送请求请求头信息不包含Cookie信息 详细问题 使用VueSpringBoot进行项目开发,axios进行网络请求,发送请求,请求头信息不包含Cookie信息 具体如下 实际效果 预期效果 解决方案 作用域 Vue项目全局配置 打开Vue项目的入口…...
正则表达式笔记
/你的正则表达式写在这里/ 1? 1出现0次或1次 1* 1出现0次或多次 1 1出现1次或多次 1{2} 1出现了2次 1{2,3} 1出现了2到3次 1{2,} 1出现了2次及以上 (5555){1} 5555出现了1次 (dog|cat) dog或者cat [a-zA-Z] a…...
数据结构链表(C语言实现)
绪论 机遇对于有准备的头脑有特别的亲和力。本章将讲写到链表其中主要将写到单链表和带头双向循环链表的如何实现。 话不多说安全带系好,发车啦(建议电脑观看)。 附:红色,部分为重点部分;蓝颜色为需要记忆的…...
Springboot实现接口传输加解密
前言 先给大家看下效果,原本我们的请求是这样子的 加密后的数据传输是这样子的 加解密步骤: 1.前端请求前进行加密,然后发送到后端 2.后端收到请求后解密 3.后端返回数据前进行加密 4.前端拿到加密串后,解密数据 加解密算法&…...
TypeScript类型系统:强类型的优势和使用方式
目录 引言强类型的优势更好的代码可读性更好的代码可维护性更好的代码重构能力更好的代码可靠性更好的代码重用能力 使用方式声明变量类型函数参数和返回值类型类型别名泛型类型(了解) 总结 引言 在上一篇文章《TypeScript入门指南:从JS到TS的…...
大数据零基础学习day1之环境准备和大数据初步理解
学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 (1)设置网关 打开VMware虚拟机,点击编辑…...
页面渲染流程与性能优化
页面渲染流程与性能优化详解(完整版) 一、现代浏览器渲染流程(详细说明) 1. 构建DOM树 浏览器接收到HTML文档后,会逐步解析并构建DOM(Document Object Model)树。具体过程如下: (…...
苍穹外卖--缓存菜品
1.问题说明 用户端小程序展示的菜品数据都是通过查询数据库获得,如果用户端访问量比较大,数据库访问压力随之增大 2.实现思路 通过Redis来缓存菜品数据,减少数据库查询操作。 缓存逻辑分析: ①每个分类下的菜品保持一份缓存数据…...
根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:
根据万维钢精英日课6的内容,使用AI(2025)可以参考以下方法: 四个洞见 模型已经比人聪明:以ChatGPT o3为代表的AI非常强大,能运用高级理论解释道理、引用最新学术论文,生成对顶尖科学家都有用的…...
AI,如何重构理解、匹配与决策?
AI 时代,我们如何理解消费? 作者|王彬 封面|Unplash 人们通过信息理解世界。 曾几何时,PC 与移动互联网重塑了人们的购物路径:信息变得唾手可得,商品决策变得高度依赖内容。 但 AI 时代的来…...
A2A JS SDK 完整教程:快速入门指南
目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库ÿ…...
【C++特殊工具与技术】优化内存分配(一):C++中的内存分配
目录 一、C 内存的基本概念 1.1 内存的物理与逻辑结构 1.2 C 程序的内存区域划分 二、栈内存分配 2.1 栈内存的特点 2.2 栈内存分配示例 三、堆内存分配 3.1 new和delete操作符 4.2 内存泄漏与悬空指针问题 4.3 new和delete的重载 四、智能指针…...
JS手写代码篇----使用Promise封装AJAX请求
15、使用Promise封装AJAX请求 promise就有reject和resolve了,就不必写成功和失败的回调函数了 const BASEURL ./手写ajax/test.jsonfunction promiseAjax() {return new Promise((resolve, reject) > {const xhr new XMLHttpRequest();xhr.open("get&quo…...
淘宝扭蛋机小程序系统开发:打造互动性强的购物平台
淘宝扭蛋机小程序系统的开发,旨在打造一个互动性强的购物平台,让用户在购物的同时,能够享受到更多的乐趣和惊喜。 淘宝扭蛋机小程序系统拥有丰富的互动功能。用户可以通过虚拟摇杆操作扭蛋机,实现旋转、抽拉等动作,增…...
[论文阅读]TrustRAG: Enhancing Robustness and Trustworthiness in RAG
TrustRAG: Enhancing Robustness and Trustworthiness in RAG [2501.00879] TrustRAG: Enhancing Robustness and Trustworthiness in Retrieval-Augmented Generation 代码:HuichiZhou/TrustRAG: Code for "TrustRAG: Enhancing Robustness and Trustworthin…...
