How do I know when the last member launches Phaser.arrive ()?

Given:

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

I would like to know if I am the last task to run doSomething() , which depends on the internal state of the task. I found Phaser.onAdvance (int, int) , but it is not clear how to use it in this case.

+4
source share
2 answers

I can't think of a very elegant way to solve this problem, but using ThreadLocal and onAdvance can help.

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

Then

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

Since you seem to know a priori how many tasks you have, just use a separate AtomicInteger .

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

Or, if you need to call doSomething until you have notified of inactive parties, just override onAdvance and do it from there.

 final Phaser phaser = new Phaser (n) { protected boolean onAdvance(int phase, int registeredParties) { doSomething(this); return super.onAdvance(phase, registeredParties); } }; 
0
source

All Articles