Java 重入锁和同步的实现有何不同

Java 重入锁和同步的实现有何不同,java,reflection,concurrency,locking,reentrantlock,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,

根据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的值是内存中状态的偏移量(使用反射)

从上面的代码中我可以理解的是,当我们调用lock.lock()时,checked-in内存中state字段的第一个值,如果它为零,则只为调用线程提供lock

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

还有一个疑问,在我读到的某个地方,可重入锁允许多个等待队列,这意味着什么?我们不是两个都只有一个队列吗

可重入锁允许多个等待队列,这意味着什么

这意味着您可以从一个
ReentrantLock
对象获取多个
Condition
对象。当一个线程需要等待某个受锁保护的对象的原因不止一个时,这一点非常有用

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

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


当我们使用
synchronized
关键字时会发生什么

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

至于它是如何实施的,。。。这在不同的体系结构上可能不同,在不同的操作系统上也可能不同。在最低级别上,它可能类似于
ReentrantLock
的工作方式,因为大多数硬件体系结构都提供了一种合理的方法来实现这一点。但是
synchronized
实现(如果有的话)和
ReentrantLock
实现所使用的中级API和库的细节可能会有所不同。唯一确定的方法是检查JVM和库源代码

可重入锁允许多个等待队列,这意味着什么

这意味着您可以从一个
ReentrantLock
对象获取多个
Condition
对象。当一个线程需要等待某个受锁保护的对象的原因不止一个时,这一点非常有用

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

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


当我们使用
synchronized
关键字时会发生什么

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


至于它是如何实施的,。。。这在不同的体系结构上可能不同,在不同的操作系统上也可能不同。在最低级别上,它可能类似于
ReentrantLock
的工作方式,因为大多数硬件体系结构都提供了一种合理的方法来实现这一点。但是
synchronized
实现(如果有的话)和
ReentrantLock
实现所使用的中级API和库的细节可能会有所不同。唯一确定的方法是检查JVM和库源代码。

“(使用反射)”-不,没有使用反射。它在这里没有用,而且速度太慢了。要了解同步的工作原理,只需阅读有关同步工作原理的教程。不,实现与ReentrantLock不同,尽管它实现了许多非常相似的目标,但并不是所有目标(如果实现了,就不需要ReentrantLock),根据grepcode,我可以看到stateOffset=unsafe.objectFieldOffset(AbstractQueuedSynchronizer.class.getDeclaredField(“state”);当然,ReentrantLock比我所写的要多得多,但我在ReentrantLock状态值decision中的问题是,锁是可用的还是被其他线程锁定的。在Synchronized中会发生什么?我找不到任何给定的链接,当我们使用Synchronized时jvm内部会做什么。“(使用反射)”-不,没有使用反射。它在这里没有用,而且速度太慢了。要了解同步的工作原理,只需阅读有关同步工作原理的教程。不,实现与ReentrantLock不同,尽管它实现了许多非常相似的目标,但并不是所有目标(如果实现了,就不需要ReentrantLock),根据grepcode,我可以看到stateOffset=unsafe.objectFieldOffset(AbstractQueuedSynchronizer.class.getDeclaredField(“state”);当然,ReentrantLock比我所写的要多得多,但我在ReentrantLock状态值decision中的问题是,锁是可用的还是被其他线程锁定的。在Synchronized中会发生什么?我找不到任何给定的链接,当我们使用Synchronized时jvm内部会做什么。