首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ReentrantLock与CompletableFuture

ReentrantLock与CompletableFuture
EN

Stack Overflow用户
提问于 2020-01-14 11:24:58
回答 1查看 617关注 0票数 0

在CompletableFuture世界之前,如果我想锁定一个变量,我可以这样做:

代码语言:javascript
复制
  private ReentrantLock myLock = new ReentrantLock();
  private List<UUID> myLockableList = new ArrayList<>();

  public void doStuff()
  {
    try
    {
      myLock.lock();
      myLockableList.clear();
    }
    finally
    {
      if (myLock.isLocked())
      {
        myLock.unlock();
      }
    }
  }

(显然,这是一个非常简单的例子,我还有其他方法试图在myLockableList上操作)。

根据ReentrantLock的说法,三种场景中的一种会发生:

  • 如果锁未被另一个线程持有,则获取该锁并立即返回,将锁保持计数设置为1。
  • 如果当前线程已经持有锁,则持有计数将增加1,并且该方法将立即返回。
  • 如果锁由另一个线程持有,则当前线程将被禁用以用于线程调度,并且处于休眠状态,直到锁被获取,此时锁保持计数被设置为1。

这一切都很好,而且正是我期望它的表现:如果在同一个线程中工作,我应该知道我是否锁定了资源,如果另一个线程已经锁定了资源,我希望等到它可用为止。

进入CompletableFutures..。

代码语言:javascript
复制
  private ReentrantLock myLock = new ReentrantLock();
  private List<UUID> myLockableList = new ArrayList<>();

  public CompletionStage<Void> doStuff()
  {
    return CompletableFuture.runAsync(() -> {
      try
      {
        myLock.lock();
        myLockableList.clear();
      }
      finally
      {
        if (myLock.isLocked())
        {
          myLock.unlock();
        }
      }
    });
  }

我希望CompletableFuture的行为也是一样的。但是,CompletableFuture可能使用一个新线程来执行上面的内容,或者(如果我的理解是正确的)它可能使用一个已经在使用的线程。如果第二个发生了(被重用的线程已经获得了锁),那么我的锁不会暂停线程并等待锁,相反,它可能会立即返回(看起来就像获得了锁一样)!

我似乎在文档中找不到明确的答案。我正确地理解了情况吗?如果是这样,那么在使用CompletableFuture时我们应该如何锁定资源呢?

非常感谢您的建议!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-01-14 16:47:02

除了评论中推荐的并发教程之外,用于ReentrantLock的Javadoc还有很好的信息值得阅读。

例如,这一点:

ReentrantLock属于线程最后成功锁定的线程,但尚未解除锁定。

您的示例使用isLocked(),Javadoc说您不应该这样做:

该方法用于监测系统状态,而不是用于同步控制。

最后,Javadoc包含一个很好的使用示例,在"try“块中显示lock(),在" Finally”块中显示unlock()

推荐的做法是始终立即按照调用使用try块锁定,最典型的情况是在构造之前/之后,例如:

代码语言:javascript
复制
 class X {
   private final ReentrantLock lock = new ReentrantLock();
   // ...

   public void m() {
     lock.lock();  // block until condition holds
     try {
       // ... method body
     } finally {
       lock.unlock()
     }
   }
 }
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59732830

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档