高级java每日一道面试题-2024年7月25日-并发篇-你对Synchronized了解多少?

面试官: 你对Synchronized了解多少?

我回答:

Synchronized是Java中的一个关键字,它提供了一种简单的同步机制来控制对共享资源的并发访问。通过Synchronized,可以确保在同一时刻只有一个线程可以进入被Synchronized修饰的代码块或方法,从而避免多个线程同时修改共享资源,解决了竞态条件和数据不一致性问题。

Synchronized的使用

同步方法
  • 实例方法

    • 语法:public synchronized void methodName() {...}
    • 效果:获取当前对象的锁,只有获取到锁的线程才能进入同步方法。
    • 说明:当一个线程进入一个对象的一个synchronized实例方法后,其它线程不可进入此对象的其它synchronized实例方法。
  • 静态方法

    • 语法:public static synchronized void methodName() {...}
    • 效果:获取类的锁,只有获取到锁的线程才能进入同步方法。
    • 说明:当一个线程进入一个对象的静态synchronized方法后,其它线程不可进入此对象的其它静态synchronized方法。
同步代码块
  • 语法
    • synchronized (object) { ... }
    • 其中object是任何对象,通常称为锁对象。
    • 效果:获取锁对象的锁,只有获取到锁的线程才能进入同步代码块。

Synchronized的实现原理

Synchronized的关键字实际上是基于对象监视器(Monitor)的概念实现的。每个Java对象都可以成为一个监视器锁。当线程试图进入同步代码块或方法时,它会尝试获取锁对象的监视器锁。如果锁可用,则获取锁并继续执行;否则,线程将被阻塞直到锁可用。
Synchronized的原理主要基于Java虚拟机(JVM)的监视器锁(Monitor Lock)机制。在Java中,每个对象都有一个对象头(Object Header),其中包含了对象的元数据信息以及锁状态。Synchronized就是通过对象头中的锁状态来实现线程同步的。

监视器锁的实现
  • 轻量级锁

    • 在没有竞争的情况下,Synchronized使用轻量级锁。
    • 轻量级锁使用Thread ID和栈帧来实现。
    • 当线程试图获取锁时,如果锁是轻量级的并且没有其他线程竞争,那么线程可以直接获取锁。
    • 如果有竞争,则升级为重量级锁。
  • 重量级锁

    • 当多个线程竞争同一个锁时,Synchronized使用重量级锁。
    • 重量级锁会导致线程阻塞,从而降低性能。
    • 重量级锁使用操作系统的互斥量来实现。
  • 偏向锁

    • 当一个线程首次获取锁时,JVM会尝试使用偏向锁。
    • 偏向锁假设锁不会被其他线程竞争,从而提高锁的性能。
    • 如果其他线程试图获取锁,偏向锁会被撤销,升级为轻量级锁或重量级锁。

Synchronized的特性

  • 可重入

    • Synchronized支持可重入性,这意味着一个线程可以多次获取同一个锁。
    • 每次获取锁时,计数器递增,每次释放锁时计数器递减,直到计数器为零时锁才被释放。
  • 公平性

    • 默认情况下,Synchronized是非公平的,这意味着线程获取锁时不一定遵循先进先出的原则。
    • 如果需要公平性,可以使用ReentrantLock的公平锁模式。
  • 异常处理

    • 如果同步代码块中抛出异常,Synchronized会自动释放锁,防止死锁。

Synchronized的优点和缺点

优点

  1. 简单易用Synchronized是Java内置的锁机制,使用起来非常简单,不需要额外的依赖。
  2. 高效:其实现非常高效,不会消耗过多的系统资源。

缺点

  1. 可重入性有限:虽然Synchronized支持可重入性,但同一个线程在持有锁的同时,不能获取该对象的其他锁。
  2. 不能协调多个线程:它只能协调两个线程之间的同步,对于需要协调多个线程之间的同步场景可能不够灵活。

与其他锁的比较

  • java.util.concurrent.locks.Lock接口相比,Synchronized更加简单易用,但功能相对较少。Lock接口提供了比Synchronized更丰富的锁操作,如尝试获取锁、定时获取锁、中断获取锁等。在实际应用中,可以根据具体需求选择合适的锁机制。

  • 综上所述,Synchronized是Java中一种重要的同步机制,通过它可以有效地确保多线程环境下共享资源的安全访问。在面试中,对Synchronized有深入的了解并能够清晰地阐述其原理、用法以及优缺点是非常重要的。

Synchronized vs. ReentrantLock
  • 灵活性

    • ReentrantLock提供了更多高级功能,如尝试锁、公平锁、锁中断等。
    • Synchronized使用起来更简单,但在某些场景下不够灵活。
  • 性能

    • 在没有锁竞争的情况下,Synchronized的性能可能更好,因为它使用了偏向锁和轻量级锁。
    • 当有多个线程竞争锁时,ReentrantLock可能表现得更好,因为它提供了更多的控制选项。

使用场景

  • 资源访问控制:保护共享资源,确保线程安全。
  • 方法同步:确保多线程环境中的方法调用顺序。
  • 代码块同步:在需要精确控制锁的地方使用。

总结

Synchronized是Java中实现线程同步的基本机制之一。它通过监视器锁的概念实现了方法和代码块的同步,支持可重入性,并且在JVM层面进行了优化以提高性能。在使用Synchronized时,需要考虑锁的竞争情况和锁的粒度,以平衡性能和线程安全性。

  • 8
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

java我跟你拼了

您的鼓励是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值