1

我必须在主线程中等待工作线程的终止,然后(在某些情况下)我启动这些线程并再次等待终止,等等。

通话join()效果很好,但我想做得更快。

Phaser 看起来像我正在寻找的东西,但我做错了:

//*** 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()?
4

1 回答 1

1

问题是您无法phaser.register()从正在注册的任务中调用。使用移相器时,请始终遵循以下两条规则:

  1. 只有注册的任务才能注册其他任务。这意味着任务不能注册自己。
  2. 所有已注册的任务必须在结束前取消注册。一个好的做法是使用移相器将代码包装finally在最后取消注册的块周围(参见示例)。

以下是更改原始示例的方法:

//*** 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();
于 2016-06-06T22:33:41.250 回答