项目中使用了非阻塞队列,如下接口目的是实现阻塞队列的处理数据。
public interface IPoller {
public void addResulst(Map resut);
public void handle();
}
这个没有针对queue的关闭,必然会导致在正常退出或者JVM 退出时queue里面的数据不能处理。在使用queue等存储临时数据时必须要安全的关闭,防止数据丢失,如此增加如下处理
public class Poller implements IPoller, BeanFactoryPostProcessor, DisposableBean
private final LinkedBlockingQueue<Map> queue = new LinkedBlockingQueue<Map>();
/*
* (non-Javadoc)
* @see org.springframework.beans.factory.DisposableBean#destroy()
*/
public void destroy() throws Exception {
if (logger.isDebugEnabled()) {
logger.debug("<<<<<<<start to close Poller in container.>>>>>>>>");
}
if (queue != null && queue.size() > 0) {
for (int i = 0; i < queue.size(); i++) {
handle();
logger.debug("<<there is " + queue.size() + "exist in queue.>>");
}
}
}
如此可以将queue里面数据处理完毕再退出, 如果要做进一步处理,可以增加JVM钩子,在JVM退出时也能够处理数据,JVM钩子的使用可以参考这个
但是如上方法都不能保证处理完数据,当数据非常大时,短时间内处理不完,则会强制退出,改天找个例子再验证下。
JAVA源代码中对于关闭的逻辑有不少可以参考,一般会提供给你一个关闭的方法,用于退出时主动关闭。
比如在util.Timer 中可以看到如下的退出逻辑
public void cancel() {
synchronized(queue) {
thread.newTasksMayBeScheduled = false;
queue.clear();
queue.notify(); // In case queue was already empty.
}
}