Comment bloquer et attendre en utilisant AtomicBoolean

Je cherche un moyen de mettre un fil en pause.

J’ai commencé par utiliser de manière affective un drapeau booléen (appelé ‘en pause’) et en enveloppant un contrôle d’une boucle while (pause).

Dans la boucle while, un Thread.wait() bloque l’exécution.

J’ai examiné AtomicBoolean , qui semble faire l’affaire, à part qu’il ne bloque pas.

Existe-t-il une version alternative ou étendue d’AtomicBoolean disposant d’une méthode de blocage?

C’est à dire quelque chose comme AtomicBoolean.getFalse() de AtomoicBoolean.get(false) ?

Ils ont une queue de blocage, donc une valeur de blocage.

La configuration actuelle est:

 while (paused.get()) { synchronized (paused) { try { paused.wait(); } catch (Exception e) { } paused.notify(); } } 

avec

 public void pause() { if (paused.compareAndSet(false, true)) { synchronized (paused) { paused.notify(); } } } public void resume() { if (paused.compareAndSet(true, false)) { synchronized (paused) { paused.notify(); } } } 

  AtomicBoolean lock = new AtomicBoolean(false); if(lock.compareAndSet(false, true)){ try { //do something } catch(Exception e){ //error handling } finally { lock.set(false); } } 

Tout d’abord, à moins d’utiliser une opération atomique (quelque chose comme test-and-set), AtomicBoolean est aussi inutile qu’un booléen normal (s’ils étaient mutables). Ici, j’utilise compareAndSet , de sorte qu’il entre uniquement dans la section critique si l’indicateur était baissé. N’oubliez pas de toujours déverrouiller dedans enfin.

Pour mettre en pause un fil à l’aide d’un drapeau, n’attendez pas une attente active (une boucle dans le corps du fil demandant “Suis-je en pause?”), Car ce n’est pas une pratique efficace. J’utiliserais un système d’attente et de notification. Lorsque le thread n’a plus de travail à faire, il appelle wait sur un object. Ensuite, pour redémarrer, certains autres appels de threads notify ce même object.

Si vous souhaitez mettre immédiatement en pause (en termes d’exécution de l’exécution lorsque l’indicateur est défini), vous pouvez diviser le code en autant d’étapes que possible, et envelopper chacune d’elles avec un test, pour finalement attendre si elle est suspendue:

 public void run(){ while(true){ if(!paused){ //do something } if(!paused){ //do something } if(!paused){ //do something } if(!paused){ //do something } if(paused){ //wait on some object } } } 

En fonction de votre code, les étapes peuvent même être nestedes ou inclure des unités d’exécution non divisibles comportant plusieurs étapes.

Utilisez un CountDownLatch de 1:

 CountDownLatch conditionLatch = new CountDownLatch(1); 

Au lieu où vous voulez attendre qu’une condition devienne vraie:

 conditionLatch.await(); 

À l’endroit où vous souhaitez définir la condition sur true:

 conditionLatch.countDown(); 

Je ne suis pas sûr d’avoir bien compris votre question: avez-vous regardé la classe java.util.concurrent.Semaphore? Un sémaphore avec permis = 1 devrait vous donner le comportement souhaité, vous pouvez émuler votre

en pause = vrai;

instruction avec

semaphore.tryAcquire ();

ou

sémaphore.acquire ();

si vous voulez verrouiller l’appelant. Vous pouvez libérer le fil avec

semaphore.release ();

Vous pouvez utiliser un verrou.

Dans ton fil.

 while(!Thread.interrupted()) { lock.lock(); try { // do something. } finally { lock.unlock(); } } // to pause lock.lock(); // to unpause lock.unlock(); // has to be the same thread which locked. 

Vous pouvez également dormir en fonction de la rapidité avec laquelle vous avez besoin d’un fil pour vous réveiller.

 while(atomicBoolean.get()) Thread.sleep(100); // or yield(); 

Soit vous attendez une heure spécifique, ce qui peut être fait avec Thread.sleep() soit vous devez attendre quelque chose, ce qui indiquerait que vous devez appeler wait() sur l’object que vous attendez pour être prêt.

Si vous avez réellement besoin de pouvoir manuellement indiquer à votre thread de continuer à travailler, Thread.sleep() une boucle while(true) contenant un appel Thread.sleep() et recherchez un booléen qui Thread.sleep() une break s’il est correctement défini. Je ne peux pas vraiment penser à une raison de le faire cependant.