当尝试用1000条数据并发向消息中心发送消息时,消息中心接收到消息打印了日志后,后面的日志就没有再打印出来了。100条也有这个问题,最后1条发现也是这样,于是发送一条消息断点测试:
//将消息中心介接收的数据wsData,交给线程池管理器InfoReceiveThreadPoolManager 处理
private void putReceiveCenter(WSData wsData ){
//将消息放入消息队列中
log.debug("加入消息接收队列开始:"+wsData.getMessage());
InfoReceiveThreadPoolManager poolManagert = InfoReceiveThreadPoolManager.getInstance();
poolManagert.addInfoQueue(wsData);
log.debug("加入消息接收队列结束:"+wsData.getMessage());
}
public class InfoReceiveThreadPoolManager{
private static final Logger log = Logger.getLogger(InfoReceiveThreadPoolManager.class);
private static InfoReceiveThreadPoolManager tpm = new InfoReceiveThreadPoolManager();
// 线程池维护线程的最少数量
private int CORE_POOL_SIZE = 50;
// 线程池维护线程的最大数量
private int MAX_POOL_SIZE = 100;
// 线程池维护线程所允许的空闲时间
private int KEEP_ALIVE_TIME = 0;
// 线程池所使用的缓冲队列大小
private int WORK_QUEUE_SIZE = 250;
// 消息缓冲队列
private Queue msgQueue = new LinkedList();
//获取管理器单例的消息并没有打印出来
public static InfoReceiveThreadPoolManager getInstance() {
log.debug("获取线程池管理器实例");
return tpm;
}
//如果线程池满了,消息队列也满了,则调用该handler处理
final RejectedExecutionHandler handler = new RejectedExecutionHandler() {
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
WSData data = ((ReceiveInfoTask) r).getWsData();
log.debug("消息接收中心拒绝处理,将消息再次加入消息队列中:"+data.getUuid());
boolean isAdded = false;
synchronized (msgQueue) {
isAdded = msgQueue.offer(data);
}
if(isAdded==false){
log.error("线程池满,无法添加消息:"+data.getUuid());
}
}
};
// 线程池
private final ThreadPoolExecutor threadPool = new ThreadPoolExecutor(
CORE_POOL_SIZE, MAX_POOL_SIZE, KEEP_ALIVE_TIME, TimeUnit.SECONDS,
new ArrayBlockingQueue(WORK_QUEUE_SIZE), handler);
}
getInstance方法的debug日志没有打印出来,InfoReceiveThreadPoolManager实例化出错了。
debug发现时在下面new一个threadPool的时候,传入的WORK_QUEUE_SIZE 为0,quickServer报了一个ArrayBlockingQueue的IllegalArgumentException。
由于最初的threadPool被定义为了static的,所以它所用到的WORK_QUEUE_SIZE也是static的,后来threadPool被我修改为非静态的了。这里将WORK_QUEUE_SIZE也去掉static,执行getInstance方法可以正确获线程池的实例,如代码所示。