ループ内の一部のリスナーに通知します。リスナーを呼び出すときに許容される最大処理時間を設定します。
for (Iterator it = listeners.iterator(); it.hasNext();) {
MyListener l = (MyListener) it.next();
l.notifyEvent(event);
}
私は、リスナーが通知メソッド内で何をしているのか見当がつかない - それは非常に長い時間がかかる可能性があるかの入力を待ってブロックすること。 システムの応答性を保証するために、次のリスナーで処理を続ける前に最大限の処理時間を確保したいと考えています。
メソッド呼び出しの最大処理時間を保証するために受け入れられるパターンは何ですか?私は二つの可能性を考える
:
- は、通知のための新しいスレッドを生成しました。それが時間内に戻らない場合は、新しいスレッドを作成し、次のリスナーをそのスレッドとともに処理します。最終的に最初のものが返ってきたら、ただそれを消させてください。この戦略のコード例を挙げることができますか?
- 現在処理中のリスナースレッドに割り込みを送信し、これがリターンすることを期待します。
他のアイデアやベストプラクティスはありますか?
PS:Java 1.4でjava.util.concurrentバックポートを使用しているため、j.u.c構造が使用できます。
編集:ここで私が開発した解決策です。 ExecutorServicesを使用するので、この単純な目的を達成するには少し重いです。そのスレッドがリスナに詰まるまで、追加のスレッドは1つだけ使用されます。次に、新しいExecutorService内に新しいスレッドが生成され、次のリスナーと連携します。注:このソリューションは、スレッドセーフでも同時実行可能でもありません。リスナーが独立している、とあなたは彼らの「回答」または任意のコールバックを気にしないならば、あなたは、単にリスナーに通知し、各リスナーのためのスレッドを生成することができれば1つのスレッドだけdoNotify()
private final Queue listeners = new ConcurrentLinkedQueue();
private final long timeout;
private final TimeUnit unit;
private ExecutorService threadPool = Executors.newFixedThreadPool(1);
public void doNotify(){
for (Iterator it = listeners.iterator(); it.hasNext();) {
final MyListener l = (MyListener) it.next();
Future future = threadPool.submit(new Runnable() {
public void run() {
l.notifyEvent();
}
});
try {
future.get(timeout, unit); // wait for task to be executed
} catch (InterruptedException e1) {
// ignore for now
} catch (ExecutionException e1) {
// ignore for now
} catch (TimeoutException e1) {
threadPool.shutdown(); // pool accepts no new tasks, and will exit when done
threadPool = Executors.newFixedThreadPool(1); // make new thread for next listener
}
}
}
ありがとうございます。私はそれに基づいて構築します。多くのリスナーにとって、あなたのソリューションは、私が避けたいと思う多くのスレッドを生成します。新しいスレッドは、必要な場合にのみ作成する必要があります(通常のリスナーが時間通りに応答すると仮定します)。 – Philipp
@Philipp、まあ、そういうわけで、私はスレッドプールを代替デザインの選択肢と言いました。 – aioobe