根据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()时,在内存中检查状态字段的第一个值,如果它为零,那么只有锁定给调用线程。所以我的问题是当我们使用同步关键字时会发生什么?在同步中还检查并设置了一些锁定字段?
还有一个疑问,在某处我读到可重入锁定允许多个等待队列,这意味着什么?难道我们不只有一个队列吗?
答案 0 :(得分:3)
reentrant lock允许多个等待队列,这是什么意思?
这意味着您可以从Condition
对象获取多个ReentrantLock
对象。当有一个以上的原因导致线程想要等待受锁保护的东西时,这很有用。
一个典型的例子是多生产者,多消费者队列。消费者可以使用一个Condition
来等待队列变为非空,以及生产者用来等待它变为非满的不同Condition
。这是一个优化。它确保生产者不会唤醒其他等待的生产者,消费者也不会唤醒其他等待的消费者。
如果使用synchronized
块保护队列,则无法使用相同的优化,因为o.wait()
方法无法让线程说出它正在等待的事件。
当我们使用
时会发生什么synchronized
关键字
您可以确定的唯一内容是您在Java语言规范中读到的内容:不允许两个线程同时在同一个对象上同步,内存可见性效果等。
至于如何实现,......在不同的架构上,可能在不同的操作系统上会有所不同。在最低级别,可能与ReentrantLock
的工作方式类似,因为大多数硬件架构提供了大约一种合理的方法。但synchronized
实现(如果有)和ReentrantLock
实现使用的中级API和库的详细信息可能不同。唯一可以确定的方法是检查JVM和库源代码。