Java 中可重入锁的底层原理
时间: 2023-06-20 07:04:35 浏览: 94
可重入锁是指同一线程可以多次获取同一把锁,也可以多次释放同一把锁,而不会出现死锁的情况。Java 中的可重入锁是基于独占式锁实现的,其底层原理主要是通过计数器来实现的。每次获取锁时计数器加一,释放锁时计数器减一,直到计数器归零才会真正释放锁。这样就可以保证同一线程多次获取同一把锁时,计数器值加一,释放时计数器值减一,不会出现死锁的情况。
相关问题
java锁的底层原理
Java中的锁机制是线程同步的关键,它用于控制多个线程对共享资源的访问,以避免数据竞争和并发问题。Java锁主要由`synchronized`关键字、`Lock`接口(如`ReentrantLock`)以及`Condition`类来实现。
**底层原理概述:**
1. **监视器(Monitor)和锁定:**每个对象都关联着一个监视器,当一个线程进入对象的`synchronized`代码块或方法时,它会获取该对象的监视器锁。如果另一个线程尝试获取同一对象的锁,那么线程会被阻塞直到第一个线程释放锁。
2. **互斥(Mutual Exclusion):**同一时间只有一个线程可以持有对象的锁,这就是互斥原则。其他等待的线程必须等到当前线程执行完毕并释放锁。
3. **可见性(Visibility):**当一个线程修改了共享状态后,必须调用`notify()`或`notifyAll()`方法通知其他等待的线程,使它们能够重新检查条件并获得锁。
4. **等待(Waiting)和唤醒(Signal):**`wait()`方法会让当前线程放弃锁,进入等待状态,直到被其他线程调用`notify()`或`notifyAll()`唤醒。如果等待过程中线程被中断,它会抛出`InterruptedException`。
5. **重入(Recursion):`synchronized`关键字支持一个线程在同一对象上多次获取锁,但只有在锁未被其他线程占用时才允许。
**ReentrantLock扩展:**Java的`ReentrantLock`提供了更多的灵活性,比如可选择公平锁(按等待线程顺序获取)和非公平锁(最快的线程优先获取),以及显式锁的获取和释放。此外,它还提供`tryLock()`方法用于无锁操作,以及条件变量`Condition`用于更复杂的同步场景。
redission分布式锁底层原理
Redisson是一个基于Redis的Java驻留库和对象映射器。它提供了许多分布式Java对象和服务,其中包括分布式锁。Redisson分布式锁的底层原理是通过Redis的setnx命令实现的。setnx命令可以在Redis中设置一个键值对,但只有在该键不存在时才能设置成功。因此,Redisson使用setnx命令来实现分布式锁的加锁操作。当一个线程尝试获取锁时,Redisson会在Redis中设置一个键值对,如果该键不存在,则该线程获取锁成功。如果该键已经存在,则表示锁已经被其他线程持有,该线程获取锁失败。当线程释放锁时,Redisson会删除该键值对,从而释放锁。
除了使用setnx命令外,Redisson还支持许多其他特性,例如锁的自动续期、异步执行等。此外,Redisson还支持多种部署架构,包括Redis单实例、Redis哨兵、Redis Cluster、Redis Master-Slave等。
下面是一个使用Redisson实现分布式锁的Java代码示例:
```java
Config config = new Config();
config.useSingleServer().setAddress("redis://127.0.0.1:6379");
RedissonClient redisson = Redisson.create(config);
RLock lock = redisson.getLock("myLock");
// 尝试获取锁,最多等待100秒
boolean res = lock.tryLock(100, TimeUnit.SECONDS);
if (res) {
try {
// 获取锁成功,执行业务逻辑
} finally {
lock.unlock();
}
} else {
// 获取锁失败,执行其他逻辑
}
```
阅读全文