Как я могу узнать, когда последняя партия запускает Phaser.arrive ()? - PullRequest
4 голосов
/ 27 сентября 2011

Дано:

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

Я бы хотел выяснить, являюсь ли я последним заданием для запуска doSomething(), которое зависит от внутреннего состояния задания. Я нашел Phaser.onAdvance (int, int) , но не ясно, как его использовать в этом случае.

Ответы [ 2 ]

0 голосов
/ 13 июня 2013

Поскольку вы, похоже, знаете априори , сколько у вас задач, просто используйте отдельную 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);
}

Или, если вам нужно позвонить doSomething до того, как неактивные участники будут уведомлены, просто переопределите onAdvance и сделайте это оттуда.

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

        return super.onAdvance(phase, registeredParties);
    }
};
0 голосов
/ 27 сентября 2011

Я не могу придумать очень элегантный способ решения этой проблемы, но может помочь использование ThreadLocal и onAdvance.

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

Тогда

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