Java 重入锁和同步的实现有何不同
根据java源代码 ReentrantLock的锁(非公平)如下所示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,
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内部会做什么。