0

バックグラウンド タスクを実行するシングルトン セッション Bean があります。

@Singleton
@ConcurrencyManagement(ConcurrencyManagementType.BEAN)
@TransactionManagement(TransactionManagementType.BEAN)
@Startup
public class TaskQueue {

private static final Logger LOGGER = Logger.getLogger("TaskQueue");

@Resource
private SessionContext sessionContext;

private final ArrayList<Runnable> tasks = new ArrayList<Runnable>();
private boolean running = false;

@PostConstruct
public void postConstruct() {
    LOGGER.info("postConstruct");

    running = true;
    sessionContext.getBusinessObject(TaskQueue.class).taskLoop();
}

@PreDestroy
public void preDestroy() {
    LOGGER.info("preDestroy");
    running = false;
    synchronized (tasks) {
        tasks.notifyAll();
    }
}

public void addTask(Runnable r) {
    synchronized (tasks) {
        tasks.add(r);
        tasks.notifyAll();
    }
}

@Asynchronous
public void taskLoop() {
    while (running) {
        Runnable task;
        synchronized (tasks) {
            LOGGER.info("Fetching next task...");
            if (tasks.isEmpty()) {
                try {
                    LOGGER.info("Task queue is empty. Waiting...");
                    tasks.wait();
                    LOGGER.info("Resumed");
                    continue;
                } catch (InterruptedException e) {
                    break;
                }
            }

            task = tasks.remove(0);
        }

        LOGGER.info("Executing task...");
        task.run();
    }

    running = false;
    LOGGER.info("Task queue exited");
}
}

モジュールの停止、モジュールのアンデプロイ、またはサーバーの停止を試みたときに、preDestroy()メソッドが呼び出されず、停止/アンデプロイ プロセスが続行されません。サーバーを停止する唯一の方法は、Java プロセスを強制終了することです。

Jboss EAP 6.0 を使用しています。

私のコードで何が問題になっていますか? それを修正する方法、または EJB 3.1 でバックグラウンド タスク キュー処理を行う別の方法は?

4

1 に答える 1