我有一個Singleton會話Bean執行的後臺任務:EJB 3.1的Singleton會話Bean @PreDestroy方法不叫
@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做後臺任務隊列處理的另一種方法是什麼?
不幸的是,我使用Java EE ** 6 **,其中'ManagedExecutorService'不可用。任何想法?順便說一下,因爲我一直在進行Bean Managed Concurrency,所以@Lock在這裏沒有必要。 – 2014-11-25 02:17:31
我的問題的最終解決方案是升級到Java EE 7,並使用**單線程**'ExecutorService'和'ManagedThreadFactory'。 @NBW的建議讓我在那裏,並將其標記爲公認的答案。 – 2014-11-25 07:09:31