Как я могу узнать, когда последняя партия запускает 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);
}
Я хотел бы узнать, являюсь ли я последним заданием, чтобы уволить doSomething()
это зависит от внутреннего состояния задачи. Я нашел Phaser.onAdvance(int, int), но не ясно, как использовать его в этом случае.
2 ответа
Решение
Я не могу придумать очень элегантный способ решения этой проблемы, но может помочь использование 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);
}
Так как вы, кажется, априори знаете, сколько у вас задач, просто используйте отдельный 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);
}
};