0

任意の PDF ファイルを画像に変換する Java 1.5 Web アプリケーションがあります。1枚のPDFでも全ページを一気に処理するには時間がかかりすぎるので、オンデマンドでページ処理したい。

特定のページの HTTP リクエストが到着したときに、 を使用して新しいスレッドで画像生成操作を起動/キューに入れることができることを読みました。ExecutorServiceシングル スレッド エグゼキュータに頼らずに、重複した操作 (たとえば、2 人のユーザーが同じ PDF から同じページを要求するなど) をキューに入れないようにするにはどうすればよいですか? 同期リストのようなものを使用して、ワーカー スレッドが処理しているイメージを追跡するにはどうすればよいですか (または、これを追跡するのに役立つ同期メカニズムの種類を教えてください)。

4

2 に答える 2

1

ConcurrentSkipListSetまたはConcurrentHashMapを使用して、どの PDF が処理されたか (おそらくキャッシュされているか)、または現在処理されているかを追跡できます。PDF から画像へのリクエストにはConcurrentLinkedQueueを使用します。ワーカー スレッドがキューから要求をプルすると、セット/マップに追加されます。追加が成功した場合、スレッドは要求を処理します。追加が失敗した場合、要求は既にコンテナー内にありました。

于 2013-04-14T01:20:22.253 に答える
1

ConcurrentHashMap<String, Future<String>>PDF識別子(ファイルパスなど)をキーとして使用し、変換操作自体を表すタスクを値として使用できます。

putIfAbsentメソッドはコンペア アンド セット操作ConcurrentHashMapの問題を処理でき、 のメソッドは変換が終了したかどうかを示すことができます。isDoneFuture

putIfAbsent返された場合null、指定された PDF の変換タスクがまだ存在していないことを意味します。そのためExecutorService.submit(Callable<T> task)、新しく作成した変換タスクを起動するために呼び出す必要があります。それ以外の場合は、この手順を省略して、既存のタスクが完了するまで待ちます。

モックアップ:

Future<String> conversionTask = ... // blah
Future<String> existingTask = conversions.putIfAbsent(pdfId, conversionTask);
if (existingTask != null) {
    conversionTask = existingTask;
}
// Either way, conversion is scheduled by now.

ExecutorService変換リクエストをキューに入れます。

変換が完了すると、Future<V>.get()メソッドを介して結果を取得できます。

Java EE アプリケーション内でスレッドを生成することは、仕様では許可されていないことに注意してください。一般的なアプローチは、非同期処理を JMS サービスとして分離することです。ここではApache Camelが役立ちます。

于 2013-04-14T09:31:38.343 に答える