synchronized关键字的原理
时间: 2023-11-21 15:45:38 浏览: 101
synchronized关键字用于解决多个线程之间对共享资源的同步访问问题。它可以保证同一时间只有一个线程执行被它修饰的方法或者代码块。synchronized关键字的原理是通过加锁和释放锁的机制来实现的。当一个线程获得了对象的锁后,其他线程就无法访问该对象的加锁方法或者代码块,只能等待获得锁的线程执行完成并释放锁后才能继续执行。这样就保证了同一时间只有一个线程能够访问被synchronized修饰的方法或者代码块,从而保证了对共享资源的安全访问。
相关问题
synchronized关键字底层原理
### Java 中 `synchronized` 关键字的底层实现原理
#### 同步代码块的结构
当定义一个同步方法或同步代码块时,实际上是在告诉 JVM 需要对该段代码进行锁定处理。对于给定的例子:
```java
private int i = 0;
public void fun(){
synchronized(this){
i++;
}
}
```
这段代码表示只有获得当前实例 (`this`) 的锁之后才能进入并执行 `{}` 大括号内的语句[^1]。
#### 底层编译后的指令变化
在 JVM 层面,每当遇到 `synchronized` 修饰的方法调用或是显式的 `synchronized` 块时,会转换成特定的操作码来控制锁的行为。具体来说就是通过 `monitorenter` 和 `monitorexit` 操作符来进行加锁和解锁操作。每次进入由 `synchronized` 定义的临界区之前都会先执行一次 `monitorenter` 来尝试获取对象上的监视器(即锁),而一旦退出该区域则自动触发相应的 `monitorexit` 以释放持有的锁资源[^3]。
#### 锁的状态变迁与优化策略
JVM 对于锁有着多种不同的状态管理方式,包括但不限于无锁、偏向锁、轻量级锁以及重量级锁等形式。这些状态之间的转变取决于实际运行环境中的竞争程度等因素。例如,在没有任何其他线程试图访问相同对象的情况下,默认采用的是偏向锁模式;而在多线程并发争抢同一把锁的情形下,则可能升级至更重级别的锁形式如膨胀为重量级锁[^5]。
- **无锁**:最初始状态下,对象头中仅保存一些基本信息而不涉及任何锁机制。
- **偏向锁**:允许单一线程长时间持有某个对象的独占使用权,减少不必要的上下文切换开销。
- **轻量级锁**:适用于短时间内的低冲突场景,利用原子性的 CAS (Compare And Swap) 操作快速完成上锁过程。
- **重量级锁**:当上述几种简化版无法满足需求时才会启用的传统 Monitor 实现方案,通常伴随着较高的性能损耗。
综上所述,`synchronized` 是一种基于 JVM 内部监控器机制构建而成的关键字,它能够有效地保障共享数据的一致性和可见性,尽管相比某些高级别的并发工具类而言可能会带来一定的性能损失,但在大多数情况下仍然是简单易用的选择之一。
Synchronized 关键字的底层原理
Synchronized关键字在Java中用于实现线程同步,其底层原理主要涉及 monitors(监视器)和互斥锁[^1]。当一个线程访问到synchronized修饰的方法或代码块时,它会尝试获取该对象的监视器。如果监视器当前未被其他线程持有,则线程获得监视器并继续执行;否则,线程会被阻塞,直到监视器释放。
`synchronized`与`lock`的主要区别在于:
1. 锁粒度:`synchronized`通常针对整个对象(Object实例),这意味着锁定的是对象,而不仅仅是代码块。`Lock`接口则提供了更细粒度的控制,允许对特定代码块进行锁定。
2. 易于管理:`Lock`提供了更多的灵活性,可以设置超时、公平/非公平策略以及可中断锁,而在Java的标准库中,这些特性不是`synchronized`的一部分。
3. 异常传播:在`try-finally`结构中,如果在`try`块中抛出了异常,`finally`块的资源清理不会因为异常而被跳过,这在`synchronized`中也适用。但在`Lock`上,异常可能不一定会导致锁立即释放。
示例演示(简化版):
```java
// 使用synchronized
public class SynchronizedExample {
private Object lock = new Object();
public void method() synchronized {
// 访问共享资源...
}
}
// 使用Lock
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class LockExample {
private final Lock lock = new ReentrantLock();
public void method() {
lock.lock();
try {
// 访问共享资源...
} finally {
lock.unlock();
}
}
}
```
阅读全文
相关推荐














