私は、非同期要求をファイアー・アンド・ファッションで実行できるメソッドを持っています。非同期処理のために短命のExecutorService
方法は、次のように実装されています
private void publishWorkItem(final Object payload, final ZkWorkCompleteCallback callback)
{
if (payload == null)
throw new NullPointerException();
final ExecutorService executor = Executors.newSingleThreadExecutor(PUBLISH_WORK_THREAD_FACTORY);
try
{
executor.execute(() -> {
try
{
if (callback != null)
{
final ZkWorkItem retval = publishWorkItem(payload);
callback.onCompleted(retval);
}
}
catch (final InterruptedException e)
{
// suppressed
}
catch (final Exception e)
{
LOGGER.error("Unhandled exception", e);
if (callback != null)
callback.onError(e);
}
});
}
finally
{
executor.shutdown();
}
}
問題は、私は、各非同期リクエストのための新しいExecutorServiceのExecutors.newSingleThreadExecutor
を作成する代わりに、固定のスレッドプールを使用していますということです。その理由は、publishWorkItem(payload)
メソッドがCountDownLatch#await()
を使用し、Watcher
が終了するのを待つので、実行中のスレッドをブロックするということです。これは、固定サイズのプールをすぐに使い果たすことがあります。 publishWorkItem(payload)
final CountDownLatch latch = new CountDownLatch(1);
zkClient.exists(pathToWatch, new Watcher()
{
@Override
public void process(final WatchedEvent event)
{
try
{
extractAndDelete(baos, event.getPath());
}
catch (final Exception e)
{
LOGGER.error("Unable to perform cleanup", e);
}
finally
{
latch.countDown();
}
}
}, true);
------ THIS IS THE PROBLEM (Blocks current thread) ------
latch.await();
の
簡体字コードは、だから私の質問は:そこにこの種の問題へのより良いアプローチです。
私はアプリケーションをプロファイルしましたが、パフォーマンス上の問題はありませんでした。懸念事項は、スレッドが多数作成されていることでした。
サイドノート:単純なone-linerでnullのthrowを置き換えることができます: 'Objects.requireNonNull(theObject、" theObjectはnullでないはずです) " – GhostCat
あなたのことははっきりしないので、ここで達成しようとしています。 ZKでやっていることに共通のパターンがあるかもしれないので、いくらか冗長な現在のタグの1つ以上を削除し、[zookeeper]を追加することは価値があるかもしれません。 ZK開始者ではありません。 –