简体   繁体   中英

How do I find out when the last party fires 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'd like to find out if I'm the last task in order to fire doSomething() that depends upon the task's internal state. I found Phaser.onAdvance(int, int) but it's not clear how to use it in this case.

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 before dormant parties are notified, 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);
    }
};

I can't think of a very elegant way of solving this but the use of ThreadLocal and the 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);
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM