Reputation: 343
I have to wait in main thread for termination of working threads, then (on some event) I start those threads and wait for termination again, etc.
Calling join()
works well, but I want to do it faster.
Phaser looks like what I'm searching for, but I'm doing something wrong:
//*** application start ***
//create "empty" Phaser
//*** main thread ***
//event occured - start working threads
phaser.register();
//start working threads...
phaser.arriveAndAwaitAdvance(); //add arriveAndDeregister()?
// *** working thread start ***
phaser.register();
// do sth ...
// *** working thread end ***
phaser.arrive(); // replace with arriveAndDeregister()?
Upvotes: 1
Views: 597
Reputation: 549
The problem is that you are cannot call phaser.register()
from within the task being registered. When using phasers always follow these two rules:
finally
block that deregisters at the end (see example).Here is how you would change your original example:
//*** application start ***
//create "empty" Phaser
final Phaser phaser = new Phaser(1);
//*** main thread ***
//event occurred - start working threads
for (int i = 0; i < WORKERS; i++) { // spawn some workers
phaser.register(); // register the worker thread before starting it
Thread worker = new Thread(new Runnable() {
@Override
public void run() {
try { // wrap the worker's code with a finally, so you are sure the task will deregister from the phaser.
// Worker's code
// ...
// *** working thread end ***
// last operation is:
} finally { // Very important to wrap
phaser.arriveAndDeregister();
}
}
});
worker.start();
}
// wait for working threads...
phaser.arriveAndAwaitAdvance();
// repeat pattern above: phaser.register() + worker.start()
phaser.arriveAndAwaitAdvance();
// since the main task is done it deregisters itself from the phaser
phaser.arriveAndDeregister();
Upvotes: 1