重入锁和同步的实现有何不同
How implementation of Re-entrant lock and Synchronization is different
根据 java 源代码
ReentrantLock的锁(非公平)如下
public boolean lock(){
int c=getState();
if(c==0){
compareAndSetState(0,1);
}
}
//getState method
public int getState(){
return state;
}
public boolean compareAndSetState(int expected,int update){
unsafe.compareAndSwapInt(this, stateOffset, expect, update);
}
stateOffSet 的值是 state 在内存中的偏移量(使用反射)。
我从上面的代码中可以理解的是,当我们调用 lock.lock() 时,state 字段的第一个值在内存中检查,如果它为零则只给调用线程锁。
所以我的问题是当我们使用 Synchronized 关键字时会发生什么?在 Synchronized 中是否也检查并设置了一些锁字段?
还有一个疑问,我在某处读到可重入锁允许多个等待队列,这是什么意思?我们不是只有一个队列吗?
reentrant lock allows multiple wait queue,what does that mean?
表示可以从一个ReentrantLock
对象中得到多个Condition
对象。当线程想要等待受锁保护的东西的原因不止一个时,这很有用。
一个典型的例子是多生产者、多消费者队列。您可以有一个 Condition
供消费者用来等待队列变为非空,另一个 Condition
供生产者用来等待队列变为非满。那是一种优化。它确保一个生产者不会唤醒其他等待的生产者,也不会一个消费者唤醒其他等待的消费者。
如果使用 synchronized
块保护队列,则无法进行相同的优化,因为 o.wait()
方法无法让线程说明它正在等待什么事件。
what happens when we usesynchronized
key word
您唯一可以确定的是您在 Java 语言规范中阅读的内容:不允许两个线程同时在同一对象上同步、内存可见性影响等。
至于它是如何实现的,...在不同的体系结构和可能在不同的操作系统上会有所不同。在最低级别,它 可能 将类似于 ReentrantLock
的工作方式,因为大多数硬件体系结构提供了大约一种合理的方法来做到这一点。但是 synchronized
实现(如果有)和 ReentrantLock
实现使用的中级 API 和库的细节可能不同。唯一确定的方法是检查 JVM 和库源代码。
根据 java 源代码
ReentrantLock的锁(非公平)如下
public boolean lock(){
int c=getState();
if(c==0){
compareAndSetState(0,1);
}
}
//getState method
public int getState(){
return state;
}
public boolean compareAndSetState(int expected,int update){
unsafe.compareAndSwapInt(this, stateOffset, expect, update);
}
stateOffSet 的值是 state 在内存中的偏移量(使用反射)。
我从上面的代码中可以理解的是,当我们调用 lock.lock() 时,state 字段的第一个值在内存中检查,如果它为零则只给调用线程锁。
所以我的问题是当我们使用 Synchronized 关键字时会发生什么?在 Synchronized 中是否也检查并设置了一些锁字段?
还有一个疑问,我在某处读到可重入锁允许多个等待队列,这是什么意思?我们不是只有一个队列吗?
reentrant lock allows multiple wait queue,what does that mean?
表示可以从一个ReentrantLock
对象中得到多个Condition
对象。当线程想要等待受锁保护的东西的原因不止一个时,这很有用。
一个典型的例子是多生产者、多消费者队列。您可以有一个 Condition
供消费者用来等待队列变为非空,另一个 Condition
供生产者用来等待队列变为非满。那是一种优化。它确保一个生产者不会唤醒其他等待的生产者,也不会一个消费者唤醒其他等待的消费者。
如果使用 synchronized
块保护队列,则无法进行相同的优化,因为 o.wait()
方法无法让线程说明它正在等待什么事件。
what happens when we use
synchronized
key word
您唯一可以确定的是您在 Java 语言规范中阅读的内容:不允许两个线程同时在同一对象上同步、内存可见性影响等。
至于它是如何实现的,...在不同的体系结构和可能在不同的操作系统上会有所不同。在最低级别,它 可能 将类似于 ReentrantLock
的工作方式,因为大多数硬件体系结构提供了大约一种合理的方法来做到这一点。但是 synchronized
实现(如果有)和 ReentrantLock
实现使用的中级 API 和库的细节可能不同。唯一确定的方法是检查 JVM 和库源代码。