synchronized 和 ReentrantLock 区别是什么?
2 个回答
漫天的冰雪冻结了我的心,但它冻结不了我心中的正义,我愿用我严寒的身躯冰冻这世间的邪恶。李九幽### Java 中 `synchronized` 和 `ReentrantLock` 有什么不同? #### 相似点 - **加锁方式同步**:两者都是通过加锁来实现同步的方式。 - **阻塞式同步**:当一个线程获得了对象锁并进入了同步块,其他访问该同步块的线程都会被阻塞在同步块外等待。线程的阻塞和唤醒会带来较高的代价。 #### 区别 **1. 语法和实现方式** - **`synchronized`**: - 是 Java 的关键字,是一种原生的语法层面的互斥,需要 JVM 实现。 - 编译后的字节码包含 `monitorenter` 和 `monitorexit` 指令。 - `monitorenter`:尝试获取对象锁。如果对象未被锁定,或当前线程已拥有该对象锁,则将锁的计数器加1。否则,线程会阻塞直到锁被释放。 - `monitorexit`:将锁的计数器减1。当计数器为0时,锁被释放。 - **`ReentrantLock`**: - 是 JDK 1.5 之后提供的 API 层面的互斥锁,位于 `java.util.concurrent` 包中。 - 需要显式调用 `lock()` 和 `unlock()` 方法,通常配合 `try/finally` 语句块使用。 **2. 高级功能** - **等待可中断**: - `ReentrantLock`:支持等待可中断,持有锁的线程长期不释放时,等待的线程可以选择放弃等待,避免死锁。 - `synchronized`:不支持等待可中断。 - **公平锁**: - `ReentrantLock`:可以选择公平锁或非公平锁。默认是非公平锁,通过构造函数参数设为 `true` 可以创建公平锁。 - `synchronized`:始终是非公平锁。 - **锁绑定多个条件**: - `ReentrantLock`:可以绑定多个 `Condition` 对象,支持更细粒度的线程协调。 - `synchronized`:只能通过 `Object` 的 `wait()` 和 `notify()` 方法实现线程间协调。 #### 示例代码 **`synchronized` 示例** ```java public class SynchronizedExample { private final Object lock = new Object(); public void synchronizedMethod() { synchronized (lock) { // 同步块 System.out.println("In synchronized block"); } } } ``` **`ReentrantLock` 示例** ```java import java.util.concurrent.locks.ReentrantLock; public class ReentrantLockExample { private final ReentrantLock lock = new ReentrantLock(); public void lockMethod() { lock.lock(); try { // 同步块 System.out.println("In lock block"); } finally { lock.unlock(); } } } ``` ### 关键点总结 - **`synchronized`**: - 是 Java 的原生关键字,通过 JVM 实现。 - 自动加锁和释放锁,使用简单。 - 不支持等待可中断、公平锁和多个条件绑定。 - **`ReentrantLock`**: - 是 `java.util.concurrent` 包中的类,通过 API 实现。 - 需要显式加锁和释放锁,更灵活。 - 支持等待可中断、公平锁和多个条件绑定。 ### 优缺点 - **`synchronized`**: - **优点**:语法简单,自动管理锁的生命周期。 - **缺点**:功能较少,不支持高级功能。 - **`ReentrantLock`**: - **优点**:功能强大,支持多种高级特性。 - **缺点**:使用稍复杂,需要手动管理锁的生命周期。 通过对比可以看出,`synchronized` 更加简单直观,适合基本的同步需求。而 `ReentrantLock` 提供了更丰富的功能和更高的灵活性,适用于复杂的同步场景。发布于 2023-11-08 23:23 •IP属地 宁夏举报评论收藏
入体冰凉的月光,都比不上你绝情的目光。松林synchronized是和if、else、for、while一样的关键字,ReentrantLock是类,这是二者的本质区别。既然ReentrantLock是类,那么它就提供了比synchronized更多更灵活的特性,可以被继承、可以有方法、可以有各种各样的类变量,ReentrantLock比synchronized的扩展性体现在几点上: 1. ReentrantLock可以对获取锁的等待时间进行设置,这样就避免了死锁 2. 3. ReentrantLock可以获取各种锁的信息 4. 5. ReentrantLock可以灵活地实现多路通知 另外,二者的锁机制其实也是不一样的:ReentrantLock底层调用的是Unsafe的park方法加锁,synchronized操作的应该是对象头中mark word。发布于 2021-07-01 20:36 •IP属地 云南举报评论收藏
公众号进入网站体验更佳

