Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/366.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 可重入锁实现细节_Java_Multithreading_Concurrency_Reentrantlock_Java 15 - Fatal编程技术网

Java 可重入锁实现细节

Java 可重入锁实现细节,java,multithreading,concurrency,reentrantlock,java-15,Java,Multithreading,Concurrency,Reentrantlock,Java 15,我试图理解ReentrantLock::lock方法中的一个特定细节。我将其视为: final void lock() { if (!initialTryLock()) { acquire(1); } } 首先,它尝试了这个方法:initialTryLock(我将在NonfairSync中查找),它执行以下操作: 它做了一个比较的wap(0,1),意思是如果没有人持有锁(0),我可以抓住它(1),我现在就持有锁 如果上述操作失败,它将检查请求锁的线程是否已经是所有者

我试图理解
ReentrantLock::lock
方法中的一个特定细节。我将其视为:

final void lock() {
   if (!initialTryLock()) {
       acquire(1);
   }
}
首先,它尝试了这个方法:
initialTryLock
(我将在
NonfairSync
中查找),它执行以下操作:

  • 它做了一个
    比较的wap(0,1)
    ,意思是如果没有人持有锁(
    0
    ),我可以抓住它(
    1
    ),我现在就持有锁
  • 如果上述操作失败,它将检查请求锁的线程是否已经是所有者
  • 如果失败,它将返回
    false
    ,这意味着我无法获得锁
让我们假设上述操作失败。然后,它继续在
AbstractQueuedSynchronizer
中调用
acquire

public final void acquire(int arg) {
    if (!tryAcquire(arg))
        acquire(null, arg, false, false, false, 0L);
}
它在
NonfairSync
中首先调用
tryAcquire

protected final boolean tryAcquire(int acquires) {
    if (getState() == 0 && compareAndSetState(0, acquires)) {
        setExclusiveOwnerThread(Thread.currentThread());
        return true;
    }
    return false;
}
您可以看到它再次尝试获取锁,尽管
initialTryLock
已经失败。理论上,这个
tryAcquire
可以简单地返回
false
,对吗

我认为这是一次潜在的重试,因为在调用
initialTryLock
tryAcquire
之间,锁可能已被释放。这样做的好处可能是,因为下一个操作(在
tryAcquire
失败之后)是该线程的昂贵排队。因此,我想这是有意义的(重试),因为这?

  • initialTryLock()
    包含可重入功能:

    • javadoc:
      /**
      *检查可重入性并立即获取是否锁定
      *根据公平与非公平规则提供。锁定方法
      *在中继到之前执行初始锁定检查
      *相应的AQS获取方法。
      */
      抽象布尔initialTryLock();
      
    • NonfairSync
      中的源代码:
      final boolean initialTryLock(){
      线程当前=Thread.currentThread();
      如果(compareAndSetState(0,1)){//第一次尝试未受保护
      设置ExclusiveOwnerThread(当前);
      返回true;
      }else if(getExclusiveOwnerThread()=当前){
      int c=getState()+1;
      if(c<0)//溢出
      抛出新错误(“超过最大锁计数”);
      设定状态(c);
      返回true;
      }否则
      返回false;
      }
      
      在这里:
      • 第一个
        if
        检查锁是否被取下(如果锁是自由的,则取下锁)
      • 第二个
        if
        检查获取的锁是否属于当前线程-这是重入逻辑
  • tryAcquire()
    必须由任何扩展
    AbstractQueuedSynchronizer

    • 该方法必须执行的操作在
      AbstractQueuedSynchronizer
    /**
    *尝试以独占模式获取。这个方法应该是查询
    *如果对象的状态允许在
    *独占模式,如果是,则获取它。
    * ...
    */
    受保护的布尔值tryAcquire(int arg){
    抛出新的UnsupportedOperationException();
    }
    
    • NonfairSync
      中的实现正是这样做的(并且不包含可重入功能):
    /**
    *InitialRylock预筛选后非重入病例的获取
    */
    受保护的最终布尔值tryAcquire(整数获取){
    if(getState()==0&&compareAndSetState(0,获取)){
    setExclusiveOwnerThread(Thread.currentThread());
    返回true;
    }
    返回false;
    }
    
只需添加到

tryAcquire
可以简单地返回false,对吗

没有

这一实施:

boolean-tryAcquire(整数获取){
返回false;
}
将中断AbstractQueuedSynchronizer的工作

原因是
tryAcquire()
是在
AbstractQueuedSynchronizer
中锁定的唯一方法

甚至

因此,如果
tryAcquire()
始终返回
false
,则
acquire()
将永远不会获取锁


acquire()
在多个线程争用锁时使用。

你提到的是哪个版本的java src?@Andrea my bad,我在看jdk-15;在Java12中,ReentrantLock::lock直接调用sync.acquire(1),函数initialTryLock不存在。所以你提到的代码是最近引入的。如果有人要调查,他应该参考正确的javaversion@Andrea说得好。我添加了正确的标签。谢谢,那么什么停止
NonfairSync::tryAcquire
返回
false
?它是一个具有非公共方法的非公共类。From:
tryAcquire()
用于
AbstractQueuedSynchronizer
中的多个位置。在您发现的地方,如果
tryAcquire()
什么也不做,并返回
false
,就可以了。但是在
AbstractQueuedSynchronizer
的其他地方,如果
tryAcquire()
没有遵守其在javadoc中关于
AbstractQueuedSynchronizer::tryAcquire
的合约,它将中断
AbstractQueuedSynchronizer
@dan1st right。我希望我错过了它,但是您能发现
tryAcquire
后面没有
acquire
AbstractQueuedSynchronizer
中的任何代码流吗?我确实理解遵守javadoc,但是返回
false
不会违反这一点。我的意思是,默认实现甚至会引发异常。除此之外,javadoc还表示:尝试以独占模式进行获取,而
initialTryLock
已经通过
if(compareAndSetState(0,1)实现了这一点
。顺便说一句,你必须在我发表评论时给我贴上
@
标签。我在
获取
中看到了
tryAcquire
的用法,但就我所知,它失败是完全可以的,也就是说:
获取
错误
。这让我起初有点不舒服。我现在看了代码