Аргумент ExecutorService для SwingWorker - PullRequest
0 голосов
/ 23 ноября 2018

У меня есть абстрактный класс, расширяющий SwingWorker и называемый FetchWorker, для выполнения некоторых фоновых выборок и изменения данных, которые выбираются для моего приложения.По моему FetchWorker это внутренний класс StatisticLayerController.Этот StatisticLayerController расширен двумя классами.Я инициализирую новые потоки в моем FetchWorker, чтобы выполнить некоторые вычисления.Раньше я использовал ExecutorService TrackHistoryLayerController.

Как показано ниже:

public class TrackHistoryLayerController extends StatisticLayerController
{
   private final ExecutorService heatMapAdderExecutor;
   ...

   public AdsbFetchWorker(...)  extends FetchWorker
   {
      super(...);
   }

   @Override
   protected final List<ADSBTrack> doInBackground() throws Exception
   {
      filtered.forEach( track -> {
         this.heatMapAdderExecutor.submit( new HeatmapAdderHelper( ... ) );
      } );
      while ( this.latch.getCount() != 0 )
      {
         this.publishValue( ( int ) this.latch.getCount() );
      }
      this.latch.await();
      this.publishValue( ( int ) this.latch.getCount() );
      if ( this.createImage() )
      {
         this.placeImage();
      }
      return filtered;
   }
}

Так что в этом случае HeatMapAdderHelper - это мой вспомогательный поток, который выполняет некоторые вычисления для меня.Все работало и все было хорошо.Но теперь я хотел немного изменить структуру классов, я хотел сделать свой Controller класс abstract, и я больше не хотел, чтобы мои Worker классы были внутренним классом.


Мой вопрос заключается в том, что я не могу (не должен) создавать ExecutorService в пределах Worker, так как рабочий будет инициализироваться каждый раз, когда вызывается событие.Единственное, что я мог сделать, это передать ExecutorService из Controller в качестве аргумента SwingWorker, но будет ли это хорошей практикой?Заранее спасибо.

1 Ответ

0 голосов
/ 23 ноября 2018

Конечно, вы также можете просто использовать значение по умолчанию ExecutorService, предоставленное CompletableFuture, выполнив

filtered.forEach( track -> {
     CompletableFuture.runAsync(new HeatmapAdderHelper( ... ) );
  } );

В качестве примечания, это

  while ( this.latch.getCount() != 0 )
  {
     this.publishValue( ( int ) this.latch.getCount() );
  }
  this.latch.await();
  this.publishValue( ( int ) this.latch.getCount() );

выглядит очень хитроумно... занятой цикл в ожидании результатов?Кроме того, почему вы await защелка после того, как вы уже ждали в цикле?Предполагая, что защелка CountDownLatch.

Я уверен, что если бы вы предоставили еще больше контекста, мы могли бы дать лучшее общее решение.

Похоже, вы можете просто сделать что-то вроде

CompletableFuture<Void>[] futures = 
     filtered.stream().map(t -> new HeatmapAdderHelper(t))
                 .map(CompletableFuture::runAsync)
                 .toArray(CompletableFuture[]::new);
CompletableFuture.allOf(futures).andThen(createImage());

Илис CountDownLatch:

CountDownLatch latch = new CountDownLatch(filtered.size());
filtered.forEach(f -> {
    CompletableFuture.runAsync(new HeatmapAdderHelper(f))
                     .thenRun(latch::countDown);
});
latch.await();
createImage();
...