news 2026/8/19 14:24:41

一把锁的两种承诺:synchronized如何同时保证互斥与内存可见性?

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
一把锁的两种承诺:synchronized如何同时保证互斥与内存可见性?

多线程环境中,‌临界区(Critical Section)是指一次只能由一个线程执行的代码段,这些代码通常涉及对共享资源(如变量、数据结构、文件或数据库连接)的访问或修改。临界区的存在是为了解决并发控制中的两大核心问题。

‌ 1)数据不一致性‌:如果多个线程同时对共享资源进行写操作,可能会破坏数据的完整性,导致其状态与预期不符。

‌ 2)竞态条件:程序的执行结果依赖于线程调度和执行的偶然顺序,这使得程序行为变得不可预测,难以调试。

image

为了保护临界区,Java提供了多种互斥(Mutual Exclusion)机制,其中synchronized关键字是最常用且强大的工具之一。

synchronized实现互斥的基础是Java中的每一个对象都可以作为锁,这个锁是排他的,在任意时刻只有两种状态:被占用和未被占用。当线程请求一个由其他线程持有的锁时,请求的线程会被阻塞,直到锁被释放。这种机制确保了在任何时刻,只有一个线程能够进入临界区执行代码。

synchronized 有两种使用方式。

1)synchronized修饰方法:锁是当前实例对象。它修饰的方法称为同步方法。

public synchronized void method() {

// ...

}

2)synchronized修饰代码块:锁是synchronized括号里配置的对象。它修饰的代码块称为同步代码块。

public void method() {

synchronized (this) {

// ...

}

}

synchronized与happens-before关系

在Java内存模型中,对synchronized关键字建立如下的happens-before关系:释放锁的操作happens-before之后对同一把锁的获取的锁操作。

class LockingExample {

int x = 0;

public synchronized void set() { // 1

x++; // 2

} // 3

public synchronized void get() { // 4

int i = x; // 5

// ......

} //6

}

假设线程A执行set()方法,随后线程B执行get()方法。

假设线程A获取锁执行set()方法,在set()方法中,对共享变量x自增+1,然后释放锁。线程B获取锁执行get()方法,在get()方法中,读取变量x,并赋值给本地变量i,然后释放锁。根据happens-before规则,可以确定线程A对x的修改happens-before线程B对x的读取,从而保证了数据的一致性。

这个过程建立的happens-before关系可以分为3类。

1)程序次序规则:1 happens-before 2,2 happens-before 3;4 happens-before 5,5 happens-before 6;

2)监视器锁规则:3 happens-before 4;

3)happens-before的传递性规则: happens-before 5。

上述happens-before关系的图形化表现形式如下。

image

synchronized内存语义

synchronized释放锁的内存语义:当线程释放锁时,Java内存模型会把该线程对应的本地内存中的共享变量刷新到主内存中。

A线程释放锁后,共享数据的状态如图所示。

image

synchronized获取锁的内存语义:当线程获取锁时,Java内存模型会把该线程对应的本地内存置为无效。从而使得被监视器保护的临界区代码必须从主内存中读取共享变量。

B线程释放锁后,共享数据的状态如图所示。

image

对比锁释放-获取与volatile写-读的内存语义可以看出:锁释放与volatile写有相同的内存语义;锁获取与volatile读有相同的内存语

义。这表明synchronized不仅提供了互斥访问的同步机制,还具备了volatile的内存可见性保障。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/18 6:16:42

从“人找信息”到“信息找人”:气象服务模型如何主动推送风险,守护全域安全?

一、传统气象服务的“最后一公里”困境当前风险信息传递的三大断层:信息过载与决策瘫痪一座城市日均产生超过500条气象预警信息企业安全官每天需要查阅20个气象平台真正与企业相关的关键信息占比不足5%“预警疲劳”导致重要风险被忽视专业术语的理解鸿沟“对流有效位…

作者头像 李华
网站建设 2026/8/19 13:55:31

VSCode的Cirq插件你真的会用吗?(90%开发者忽略的3个高级功能)

第一章:VSCode的Cirq插件概述VSCode的Cirq插件为量子计算开发者提供了高效的开发环境支持,专为使用Google开源框架Cirq进行量子电路设计与仿真的工程师和研究人员量身打造。该插件集成了语法高亮、智能补全、错误提示以及代码片段等功能,显著…

作者头像 李华
网站建设 2026/8/18 17:36:05

VectorDBBench 向量数据库性能基准测试终极指南

VectorDBBench 向量数据库性能基准测试终极指南 【免费下载链接】VectorDBBench 项目地址: https://gitcode.com/gh_mirrors/ve/VectorDBBench 在AI应用和向量搜索日益普及的今天,选择合适的向量数据库成为技术决策的关键环节。面对市场上琳琅满目的向量数据…

作者头像 李华
网站建设 2026/8/18 14:35:33

5个技巧让你的网页播放器实现专业级录像回放功能

5个技巧让你的网页播放器实现专业级录像回放功能 【免费下载链接】jessibuca Jessibuca是一款开源的纯H5直播流播放器 项目地址: https://gitcode.com/GitHub_Trending/je/jessibuca 你是否曾经在使用网页播放器时遇到过这些问题:时间轴拖动不精确、倍速播放…

作者头像 李华
网站建设 2026/8/18 19:29:06

终极HTML5音效生成器指南:用jsfxr让游戏开发音效制作零门槛

还在为游戏音效制作发愁吗?jsfxr这款基于HTML5的开源音效生成器将彻底改变你的创作体验。无需专业音频知识,无需昂贵软件,在浏览器中就能轻松制作出专业级的游戏音效,让独立游戏开发者的音效制作变得前所未有的简单高效。 【免费下…

作者头像 李华
网站建设 2026/8/19 1:50:24

IDM激活脚本深度解析:技术原理与实战指南

IDM激活脚本深度解析:技术原理与实战指南 【免费下载链接】IDM-Activation-Script IDM Activation & Trail Reset Script 项目地址: https://gitcode.com/gh_mirrors/id/IDM-Activation-Script Internet Download Manager(IDM)作为…

作者头像 李华