SwingWorker 的 ExecutorService 参数
ExecutorService argument to SwingWorker
我有一个抽象 class 扩展 SwingWorker
称为 FetchWorker
来执行一些后台数据获取和修改为我的应用程序获取的数据。在我的 FetchWorker
中是 StatisticLayerController
的内部 class。这个 StatisticLayerController 由两个 class 扩展。我在 FetchWorker
中初始化新线程以进行一些计算。我以前用的是TrackHistoryLayerController.
的ExecutorService
如下所示:
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
是我的助手线程,它为我做了一些计算。一切正常,一切都很好。
但是现在我想稍微改变一下 class 结构,我想让我的 Controller
class abstract
而我不再想要我的 Worker
classes 是一个内部 class。
我的问题是,我不能(不应该)在 Worker
中创建 ExecutorService
,因为每次调用事件时都会初始化 worker。我唯一能做的就是将 Controller
中的 ExecutorService 作为参数传递给 SwingWorker
,但这是一个好习惯吗?提前谢谢你。
您当然也可以只使用 CompletableFuture
提供的默认值 ExecutorService
,方法是
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();
我有一个抽象 class 扩展 SwingWorker
称为 FetchWorker
来执行一些后台数据获取和修改为我的应用程序获取的数据。在我的 FetchWorker
中是 StatisticLayerController
的内部 class。这个 StatisticLayerController 由两个 class 扩展。我在 FetchWorker
中初始化新线程以进行一些计算。我以前用的是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
是我的助手线程,它为我做了一些计算。一切正常,一切都很好。
但是现在我想稍微改变一下 class 结构,我想让我的 Controller
class abstract
而我不再想要我的 Worker
classes 是一个内部 class。
我的问题是,我不能(不应该)在 Worker
中创建 ExecutorService
,因为每次调用事件时都会初始化 worker。我唯一能做的就是将 Controller
中的 ExecutorService 作为参数传递给 SwingWorker
,但这是一个好习惯吗?提前谢谢你。
您当然也可以只使用 CompletableFuture
提供的默认值 ExecutorService
,方法是
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();