Avant le monde de CompletableFuture, si je voulais verrouiller une variable, je pouvais le faire:

  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();
      }
    }
  }

(Évidemment, ceci est un exemple très simplifié, j'ai d'autres méthodes essayant de fonctionner sur myLockableList, aussi).

Selon ReentrantLock, 1 des 3 scénarios se produirait:

  • Acquiert le verrou s'il n'est pas détenu par un autre thread et revient immédiatement, en définissant le nombre de verrous sur un
  • Si le thread actuel détient déjà le verrou, le nombre de prises est incrémenté de un et la méthode retourne immédiatement
  • Si le verrou est détenu par un autre thread, le thread actuel est désactivé à des fins de planification de thread et reste inactif jusqu'à ce que le verrou soit acquis, date à laquelle le nombre de blocages est défini sur un.

C'est très bien et exactement comment je m'attends à ce qu'il se comporte: si je travaille dans le même thread, je devrais savoir si j'ai verrouillé la ressource, et si un autre thread a verrouillé la ressource, je voudrais attendre qu'elle devienne disponible.

Entrez CompletableFutures ...

  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();
        }
      }
    });
  }

J'espère que le comportement de CompletableFuture sera le même. Cependant, A CompletableFuture peut exécuter ce qui précède avec un nouveau thread ou, si ma compréhension est correcte, il peut utiliser un thread déjà utilisé. Si la seconde se produit (le thread en cours de réutilisation a déjà acquis le verrou), alors mon verrou ne mettra pas le thread en pause et n'attendra pas le verrou, mais il pourrait en fait revenir immédiatement (comme s'il avait acquis le verrou)!

Je n'arrive pas à trouver une réponse définitive dans la documentation. Ai-je bien compris la situation? Si oui, comment devrions-nous verrouiller les ressources lors de l'utilisation de CompletableFuture?

Merci beaucoup pour tout conseil!

0
danwag 14 janv. 2020 à 14:24