首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >撑起营销交易系统的核心:JUC

撑起营销交易系统的核心:JUC

作者头像
灬沙师弟
发布2025-11-12 13:28:10
发布2025-11-12 13:28:10
1250
举报
文章被收录于专栏:Java面试教程Java面试教程

最近了不起在整理关于JUC的学习路线,在这里也一起分享给大家。

在 Java 的多线程世界里,线程安全就像一座必须坚守的城池,而 synchronized 关键字便是守护这座城池的坚实盾牌。

从简单的单例模式实现到复杂的分布式系统交互,synchronized 始终在默默发挥着关键作用,确保多个线程在共享资源时能够有序协作,避免数据错乱的 “灾难”。

想要真正驾驭多线程编程,吃透 synchronized 的底层逻辑与实用技巧,无疑是绕不开的重要一课。

接下来,就让我们一同揭开 synchronized 的神秘面纱,从原理到实践,全方位掌握这一核心关键字。

一、synchronized 的工作原理

synchronized 基于监视器锁(Monitor Lock)实现,每个 Java 对象都内置了一个监视器锁。当线程进入 synchronized 代码块或方法时,会自动尝试获取这个锁。

若锁可用,线程便获取锁并继续执行;若锁被其他线程持有,当前线程则会被阻塞,进入等待状态,直至锁被释放。

从字节码层面来看,synchronized 的实现运用了 monitorenter 和 monitorexit 指令。

二、对象锁和类锁的区别

synchronized 可以修饰实例方法、静态方法和代码块,根据修饰目标的不同,获取的锁也有所区别,分为对象锁(实例锁)和类锁(静态锁)。

(一)对象锁

实例方法同步:当 synchronized 修饰实例方法时,线程获取的是当前对象的锁。示例代码如下:

代码语言:javascript
复制
public synchronized void method() {
    // 获取当前对象的锁
}

代码块同步:在代码块中使用 synchronized (this),线程获取的同样是当前对象的锁。示例代码如下:

代码语言:javascript
复制
public void method() {
    synchronized(this) {
        // 获取当前对象的锁
    }
}

(二)类锁

静态方法同步:synchronized 修饰静态方法时,线程获取的是类的 Class 对象的锁。示例代码如下:

代码语言:javascript
复制
public static synchronized void staticMethod() {
    // 获取类的Class对象的锁
}

Class 对象同步:在代码块中使用 synchronized (MyClass.class),线程获取的是类的 Class 对象的锁。示例代码如下:

代码语言:javascript
复制
public void method() {
    synchronized(MyClass.class) {
        // 获取类的Class对象的锁
    }
}

需要重点注意的是,对象锁和类锁是完全独立的,一个线程获取了对象锁,并不会阻碍其他线程获取类锁。

三、锁升级机制

为了提升性能,JVM 对 synchronized 进行了优化,引入了锁升级机制。

锁会依据竞争情况,从偏向锁逐步升级到轻量级锁,再到重量级锁,且这个过程是单向升级,不可降级。

偏向锁:适用于只有一个线程访问的场景,几乎没有性能开销,它会在对象头中记录线程 ID,当有其他线程竞争时便会升级。

轻量级锁:适用于线程交替执行的情况,使用 CAS 操作避免线程阻塞,会在栈帧中创建锁记录,当竞争激烈时升级为重量级锁。

重量级锁:适用于高竞争的情况,它使用操作系统的互斥量,线程会被阻塞和唤醒,性能开销最大。

四、死锁问题

死锁是多线程编程中的常见问题,当两个或多个线程相互等待对方释放锁时,就会发生死锁。

(一)死锁的四个必要条件

互斥条件:资源不能被多个线程同时使用。

持有和等待:线程持有资源的同时等待其他资源。

不可剥夺:资源不能被强制从线程中剥夺。

循环等待:存在线程资源的循环等待链。

(二)死锁示例

以下是一个经典的死锁场景代码:

代码语言:javascript
复制
public class DeadlockExample {
    privatestatic Object lock1 = new Object();
    privatestatic Object lock2 = new Object();
    
    public static void main(String[] args) {
        Thread t1 = new Thread(() -> {
            synchronized (lock1) {
                System.out.println("Thread 1: 获取lock1");
                try { Thread.sleep(100); } catch (InterruptedException e) {}
                synchronized (lock2) {
                    System.out.println("Thread 1: 获取lock2");
                }
            }
        });
        
        Thread t2 = new Thread(() -> {
            synchronized (lock2) {
                System.out.println("Thread 2: 获取lock2");
                try { Thread.sleep(100); } catch (InterruptedException e) {}
                synchronized (lock1) {
                    System.out.println("Thread 2: 获取lock1");
                }
            }
        });
        
        t1.start();
        t2.start();
    }
}

(三)死锁预防策略

锁排序:所有线程按相同顺序获取锁。

锁超时:使用 tryLock () 设置获取锁的超时时间。

死锁检测:定期检测死锁并采取恢复措施。

避免嵌套锁:尽量避免在持有锁的情况下获取其他锁。

五、性能优化

虽然 synchronized 使用简单,但在高并发场景下可能成为性能瓶颈,掌握以下优化技巧有助于提升程序性能。

(一)优化策略 减小锁粒度:将大锁拆分为多个小锁,减少锁竞争。示例如下:

代码语言:javascript
复制
// 粗粒度锁
synchronized(this) {
    updateField1();
    updateField2();
}

// 细粒度锁
synchronized(lock1) { updateField1(); }
synchronized(lock2) { updateField2(); }

锁分离:读写分离,使用 ReadWriteLock。示例如下:

代码语言:javascript
复制
ReadWriteLock rwLock = new ReentrantReadWriteLock();
Lock readLock = rwLock.readLock();
Lock writeLock = rwLock.writeLock();

锁消除:JVM 会自动消除不必要的锁。示例如下:

代码语言:javascript
复制
// 局部变量,JVM会消除同步
StringBuffer sb = new StringBuffer();
sb.append("hello");
sb.append("world");

(二)性能建议

尽量缩短同步代码块的执行时间。

避免在循环中使用 synchronized。

考虑使用并发集合类替代同步集合。

在高并发场景下考虑使用 Lock 接口。

结束

当我们梳理完 synchronized 的工作原理、锁的类型差异、升级机制、死锁问题及性能优化策略后,不难发现这个看似简单的关键字背后,蕴藏着 Java 多线程编程的深刻智慧。

它不仅是保障线程安全的基础工具,更是开发者理解 JVM 底层运行机制的重要窗口。

在实际开发中,没有放之四海而皆准的同步方案,唯有根据业务场景灵活运用 synchronized 的各项特性,才能在安全性与性能之间找到最佳平衡点。

希望通过本文的解读,你能对 synchronized 形成系统认知,并将其转化为解决实际问题的能力。若你在实践中总结出更多独到经验,欢迎在评论区分享,让我们一同在多线程编程的道路上不断精进。

福利分享时间

很多小伙伴也关注很久了

我们能与志同道合的朋友畅聊职业发展

分享最新面试机会和题库

为了更方便的交流

我们特别创建了一个专业的交流群

旨在帮助大家互相学习、共同进步

输入加群口令 mmm

即可轻松成为我们的一员

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-09-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Java面试教程 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、synchronized 的工作原理
  • 二、对象锁和类锁的区别
    • (一)对象锁
    • (二)类锁
    • 三、锁升级机制
    • 四、死锁问题
    • 五、性能优化
  • 结束
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档