2011-09-27 3 views
4

Étant donné:Comment savoir quand la dernière partie se déclenche Phaser.arrive()?

Executor executor = ...; 
Phaser phaser = new Phaser(n); 
for (int i=0; i<n; ++i) 
{ 
    Runnable task = new Runnable() 
    { 
    public void run() 
    { 
     phaser.arriveAndDeregister(); 
     if (lastTask) 
     doSomething(this); 
    } 
    } 

    // run tasks using a thread-pool (order is not guaranteed) 
    executor.submit(task); 
} 

Je voudrais savoir si je suis la dernière tâche afin de tirer doSomething() qui dépend de l'état interne de la tâche. J'ai trouvé Phaser.onAdvance(int, int) mais on ne sait pas comment l'utiliser dans ce cas.

Répondre

0

Je ne trouve pas de solution très élégante à cela, mais l'utilisation de ThreadLocal et d'onAdvance peut aider.

final ThreadLocal<Boolean> isLast = new ThreadLocal<Boolean>() { 
     public Boolean initialValue() { 
      return false; 
     } 
    }; 
    final Phaser p = new Phaser(9) { 
     public boolean onAdvance(int phase, int registeredParties) { 
      isLast.set(true); 
      return true; 
     } 
    }; 

Puis

public void run() 
    { 
     phaser.arriveAndDeregister(); 
     if (isLast.get()) 
     doSomething(this); 
    } 
0

Puisque vous semble savoir a a priori combien de tâches que vous avez, il suffit d'utiliser un AtomicInteger séparé.

int n = 5; 
ExecutorService executor = ... 
final AtomicInteger count = new AtomicInteger (n); 
final Phaser phaser = new Phaser (n); 
for (int i = 0; i < n; ++i) { 
    Runnable task = new Runnable() { 
     public void run() { 
      phaser.arriveAndDeregister(); 
      if (count.decrementAndGet() == 0) { 
       doSomething (this); 
      } 
     } 
    }; 

    // run tasks using a thread-pool (order is not guaranteed) 
    executor.submit (task); 
} 

Ou, si vous avez besoin d'appeler doSomething avant que les parties dormants sont informés, juste passer outre onAdvance et de le faire à partir de là.

final Phaser phaser = new Phaser (n) { 
    protected boolean onAdvance(int phase, int registeredParties) { 
     doSomething(this); 

     return super.onAdvance(phase, registeredParties); 
    } 
}; 
+0

Je ne pense pas que votre code doit vérifier si '(registeredParties == 0)' 'parce que onAdvance()' est garanti pour s'invoqué que lorsque tous les partis sont arrivés. S'il y a 0 parties en attente ou plus, l'événement devrait se déclencher. – Gili

+0

Tout à fait raison, édité. – rxg

Questions connexes