重入锁和同步的实现方式不同

时间:2017-03-26 14:43:21

标签: java reflection concurrency locking reentrantlock

根据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()时,在内存中检查状态字段的第一个值,如果它为零,那么只有锁定给调用线程。

所以我的问题是当我们使用同步关键字时会发生什么?在同步中还检查并设置了一些锁定字段?

还有一个疑问,在某处我读到可重入锁定允许多个等待队列,这意味着什么?难道我们不只有一个队列吗?

1 个答案:

答案 0 :(得分:3)

  

reentrant lock允许多个等待队列,这是什么意思?

这意味着您可以从Condition对象获取多个ReentrantLock对象。当有一个以上的原因导致线程想要等待受锁保护的东西时,这很有用。

一个典型的例子是多生产者,多消费者队列。消费者可以使用一个Condition来等待队列变为非空,以及生产者用来等待它变为非满的不同Condition。这是一个优化。它确保生产者不会唤醒其他等待的生产者,消费者也不会唤醒其他等待的消费者。

如果使用synchronized块保护队列,则无法使用相同的优化,因为o.wait()方法无法让线程说出它正在等待的事件。

  

当我们使用synchronized关键字

时会发生什么

您可以确定的唯一内容是您在Java语言规范中读到的内容:不允许两个线程同时在同一个对象上同步,内存可见性效果等。

至于如何实现,......在不同的架构上,可能在不同的操作系统上会有所不同。在最低级别,可能ReentrantLock的工作方式类似,因为大多数硬件架构提供了大约一种合理的方法。但synchronized实现(如果有)和ReentrantLock实现使用的中级API和库的详细信息可能不同。唯一可以确定的方法是检查JVM和库源代码。