0

0

在Java中synchronized关键字如何使用_Java线程同步基础解析

P粉602998670

P粉602998670

发布时间:2026-01-30 10:59:35

|

518人浏览过

|

来源于php中文网

原创

synchronized的核心作用是保证同一时刻只有一个线程执行被修饰的代码,其锁对象依使用方式而异:实例方法锁this、静态方法锁Class对象、代码块可显式指定锁对象;它具备可重入性与内存可见性语义。

在java中synchronized关键字如何使用_java线程同步基础解析

synchronized 的核心作用是保证同一时刻只有一个线程能执行被它修饰的代码块或方法,但它不是“万能锁”,用错位置或对象就完全失效。

同步实例方法:锁的是当前对象(this

synchronized 修饰普通成员方法时,锁对象是调用该方法的实例。不同实例之间互不影响。

  • 适用场景:多个线程操作同一个对象的共享状态(如计数器、缓存容器)
  • 常见错误:用两个不同对象调用该方法,结果没加锁——因为锁对象不同
  • 性能影响:若对象生命周期长、竞争激烈,可能成为瓶颈;但比全局锁轻量

示例:

public synchronized void increment() {
    count++;
}
等价于
public void increment() {
    synchronized(this) {
        count++;
    }
}

同步静态方法:锁的是类对象(MyClass.class

静态方法属于类,没有 this,所以锁的是当前类的 Class 对象。所有该类的实例共享这一把锁。

  • 适用场景:需要跨实例控制资源(如单例初始化、全局配置加载)
  • 容易踩的坑:误以为锁住的是“某个实例”,结果发现其他实例也阻塞了
  • 注意兼容性:在模块化环境(如 Java 9+ Module System)中,若类由不同 ClassLoader 加载,MyClass.class 不同,锁不生效

同步代码块:显式指定锁对象,最灵活也最容易出错

synchronized(锁对象) 包裹一段逻辑,锁对象可以是任意非空引用类型变量。这是最可控的方式,也是唯一能避免锁整个方法粒度太粗的方案。

Skybox AI
Skybox AI

一键将涂鸦转为360°无缝环境贴图的AI神器

下载

立即学习Java免费学习笔记(深入)”;

  • 必须确保所有相关临界区使用**同一个锁对象**,否则无效
  • 禁止用 String、常量池对象或自动装箱基本类型(如 Integer)作锁——它们可能被复用或缓存,导致意外共享
  • 推荐用私有 final Object lock = new Object();,明确、安全、不可变
  • 锁对象不能为 null,否则抛 NullPointerException

示例:

private final Object lock = new Object();
public void doSomething() {
    synchronized(lock) {
        // 仅此处受保护
        updateSharedState();
    }
}

锁升级与可重入性:别自己实现“递归锁”逻辑

synchronized 是可重入锁:同一个线程重复获取同一把锁不会死锁,会记录进入次数,退出时逐层释放。

  • 这意味着在同步方法里调用本类另一个 synchronized 方法,不会卡住
  • 但要注意:锁升级(偏向→轻量→重量)是 JVM 自动做的,开发者无法干预或感知;不要试图通过“先判断是否已持有锁”来绕过同步——既没必要,也破坏语义
  • 真正容易被忽略的是锁的可见性语义:synchronized 不仅互斥,还保证进入前读取最新值、退出后刷新到主内存——这点常被忽视,却直接影响 volatile 的取舍

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

463

2023.08.02

c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

236

2023.09.22

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

458

2024.03.01

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1502

2023.10.24

c++中volatile关键字的作用
c++中volatile关键字的作用

本专题整合了c++中volatile关键字的相关内容,阅读专题下面的文章了解更多详细内容。

69

2025.10.23

class在c语言中的意思
class在c语言中的意思

在C语言中,"class" 是一个关键字,用于定义一个类。想了解更多class的相关内容,可以阅读本专题下面的文章。

469

2024.01.03

python中class的含义
python中class的含义

本专题整合了python中class的相关内容,阅读专题下面的文章了解更多详细内容。

15

2025.12.06

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

523

2023.08.10

C++ 设计模式与软件架构
C++ 设计模式与软件架构

本专题深入讲解 C++ 中的常见设计模式与架构优化,包括单例模式、工厂模式、观察者模式、策略模式、命令模式等,结合实际案例展示如何在 C++ 项目中应用这些模式提升代码可维护性与扩展性。通过案例分析,帮助开发者掌握 如何运用设计模式构建高质量的软件架构,提升系统的灵活性与可扩展性。

8

2026.01.30

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Kotlin 教程
Kotlin 教程

共23课时 | 3万人学习

C# 教程
C# 教程

共94课时 | 8万人学习

Java 教程
Java 教程

共578课时 | 53.3万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号