java 链表并发队列 LinkedBlockingQueue 的坑

链个队比数组队的性能要高, 所以一般用 LinkedBlockingQueue 比较多, 之前并没有注意各方法有什么不同.

环境: JDK 1.8

今天发现在 LinkedBlockingQueue 有个坑:

入队方法 add不能随意使用 :

LinkedBlockingQueue< String > receiveQueue = new LinkedBlockingQueue< String >();
receiveQueue.add("123");

会导致在出队线程处理中 poll() 无法及时取得值:

/**
	 * 独立处理 队列线程
	 */
	private class receiveThread implements Runnable{
		@Override
		public void run() {
			String msg = null;
			while (receNext) {
				try {
					msg = receiveQueue.poll();
					if(msg != null) {
						//处理消息....
						logger.info("接收数据:"+ msg );
					} else {
						Thread.sleep(2000);
					}
				}catch (Exception e) {
					logger.error("接收线程异常", e);
				} finally {
					
				}
			}
		}
	}

经过查看原代码, add方法在此类中没有重写, 入队之后, 并没有触发操作, 因此是个坑.

重现的代码环境是: 

1, add方法与poll所在的线程是在同一个类中, add在类方法中调用, poll 内部类线程中调用.

2, poll的线程一直在运行, 当程序中其它代码(程序另一个线程中) 调用 add在一个方法后, poll并没有取得值.

    经测试, 这时如果要poll要取得值必须 在poll之前调用 size() 才能让poll取得值. 否则 poll在测试的 10多秒后仍然得到空值.

3, 以上是在多线程环境时出现的, 如果在同一段代码中先 add再 poll这样测试, 是可以正常取得值的.

经过测试与查看源代码, 在此类中 出队方法 receiveQueue.take(), 入队方法 receiveQueue.put(E o)  应配合使用.

由于时间限制其它方法没有再详细测试.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章