正直なところ、要件 3 はおそらく Executor から標準の ExecutorService 実装を使用するだけで簡単に満たすことができます。これにより、たとえば、固定サイズのスレッド プールを取得し、Runnable または Callable 実装の形式でそれらに作業を送信できます。彼らは、制限までスレッドを作成するなどの面倒な詳細を処理します。その後、リスナーに Runnable の薄いレイヤーを実装して、統計などを収集することができます。
何かのようなもの:
private final ExecutorService threadPool = Executors.newFixedThreadPool(THREAD_POOL_SIZE);
private final NotificationCallback callback;
private int waiting, executing, succeeded, failed;
public void pollAndDispatch() {
Notification notification;
while ((notification = pollDatabase()) != null) {
final Notification ourNotification = notification;
incrementWaitingCount();
threadPool.submit(new Runnable() {
public void run() {
waitingToExecuting();
try {
callback.processNotification(ourNotification);
executionCompleted();
} catch (Exception e) {
executionFailed();
LOG.error("Exeception thrown while processing notification: " + ourNotification, e);
}
}
});
}
}
// check PGconn for notification and return it, or null if none received
protected Notification pollDatabase() { ... }
// maintain statistics
private synchronized void incrementWaitingCount() { ++waiting; }
private synchronized void waitingToExecuting() { --waiting; ++executing; }
private synchronized void executionCompleted() { --executing; ++succeeded; }
private synchronized void executionFailed() { --executing; ++failed; }
派手にしたい場合は、通知を JMS キューに入れ、そのインフラストラクチャを使用して新しい項目をリッスンして処理します。