ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

简单讲解Java中的synchronized

简单讲解Java中的synchronized 1. 为什么需要 synchronized在多线程环境下多个线程可能同时访问和修改共享资源导致数据不一致的问题。例如两个线程同时对同一个银行账户余额进行“取款”操作可能因为操作的非原子性读-改-写导致最终结果错误。synchronized的作用就是保证同一时刻最多只有一个线程执行被它修饰的代码块或方法从而保证线程安全。2. synchronized 的三种使用方式使用方式锁对象作用范围修饰实例方法当前实例对象this整个方法体修饰静态方法当前类的Class对象整个方法体修饰代码块指定的任意对象代码块内的语句2.1 修饰实例方法 -- 锁对象是整个 thispublic class Counter { private int count 0; public synchronized void increment() { // 锁住 this count; } }2.2 修饰静态方法 -- 锁对象是整个类public class Counter { private static int count 0; public static synchronized void increment() { // 锁住 Counter.class count; } }2.3 修饰代码块最灵活-- 锁对象是lock细粒度锁只锁这一个特定的锁对象//只有显式写上 synchronized(lock)的代码块才会排队。其他方法包括synchronized方法完全不受影响可以并行执行。public class Counter { private int count 0; private final Object lock new Object(); public void increment() { synchronized (lock) { // 锁住 lock 对象 count; } } }3. 锁的是什么核心要点synchronized 不是锁代码而是锁对象。同一时刻同一个锁对象只能被一个线程持有。不同锁对象之间互不干扰。示例说明public class Example { public synchronized void methodA() {} // 锁 this public synchronized void methodB() {} // 锁 this同一个锁 public static synchronized void methodC() {} // 锁 Class }线程1 执行methodA()时线程2 不能执行methodB()因为锁是同一个this如果是不同的“this”则两个方法并不会相互影响。但线程2 可以执行methodC()因为锁是Class不同锁对象。4. 底层实现原理JVM层面监视器锁Monitor每个Java对象都有一个内部锁Monitor。synchronized本质就是获取/释放这个Monitor。字节码指令同步代码块monitorenter进入monitorexit退出可能有多个退出路径。同步方法通过方法表的ACC_SYNCHRONIZED标志隐式实现。锁升级机制JDK 1.6 优化无锁 → 偏向锁 → 轻量级锁 → 重量级锁自旋、自适应自旋、锁粗化、锁消除等优化。5. 与 volatile 的区别特性synchronizedvolatile原子性✅ 保证 要么全做要么全不做❌ 不保证可见性✅ 保证解锁前刷新到主存改了就得让人看见✅ 保证有序性✅ 保证同一时刻单线程执行代码按顺序执行不被重排✅ 保证禁止指令重排序是否阻塞是竞争失败会阻塞获取不到锁时线程是等待还是放弃否简单记volatile解决可见性synchronized解决可见性 原子性。6. 常见误区与注意事项可以通过AI简单了解锁对象不能是 null否则抛NullPointerException。锁对象尽量使用final避免引用被修改导致锁失效。不要用String常量或Integer等包装类作为锁因为常量池可能导致意外共享锁。synchronized 是可重入锁同一个线程可以多次获取同一把锁避免死锁。过度使用会降低性能应尽量缩小同步范围。7. 简单示例线程安全的计数器public class SafeCounter { private int count 0; private final Object lock new Object(); public void increment() { synchronized (lock) { count; } } public int getCount() { synchronized (lock) { return count; } } }8. 最后一句话在真正的互联网高并发业务代码中我们其实很少直接用synchronized处理业务逻辑synchronized 是 Java 内置的互斥锁通过锁住对象来保证代码块或方法在并发环境下的原子性、可见性和有序性是解决线程安全问题最直接、最可靠的手段之一。分布式场景现在的服务大多是分布式部署多台机器synchronized只能锁单台机器的JVM进程跨机器无效。我们通常用Redis分布式锁或ZooKeeper。单机高性能场景如果是单机高并发计数器、累加器我们通常直接用AtomicIntegerCAS无锁或LongAdder性能比synchronized高得多。需要等待/超时/中断的场景我们会用ReentrantLock因为它支持尝试加锁、超时等待、可中断而synchronized不支持这些高级功能。
返回列表