ArrayBlockingQueue 取出null值问题

记录工作中遇到的问题,同时也希望可以帮助到有需要的朋友

ArrayBlockingQueue  相关知识网上很多帖子写的很好,还有丰富的demo,就不在此一一赘述了

这周在使用 ArrayBlockingQueue  时遇到一个问题,明明往队列中放( 用的offer(String e, long timeout, TimeUnit unit) )入了数据,但是取( 用的poll(long timeout, TimeUnit unit) )值的时候取到的是null值。

周末在家写了个测试demo

public static void main(String[] args) {
		
		ArrayBlockingQueue blockingQueue = new ArrayBlockingQueue<>(3);
		
		new Thread(()->{
				try {
					for (int i = 0; i < 10; i++) {
						blockingQueue.offer(i+""+i,1,TimeUnit.SECONDS);
						System.out.println(Thread.currentThread().getName() +"-> 插入【"+i+i+"】成功");
					}
				} catch (InterruptedException e) {
					e.printStackTrace();
				} 
		},"t1").start();
		
		new Thread(()->{
			try {
				for (int i = 0; i < 10; i++) {
					TimeUnit.SECONDS.sleep(2);
					
					String take = blockingQueue.poll(1,TimeUnit.SECONDS);
					System.out.println(Thread.currentThread().getName() +"---> 取出【"+take+"】成功");
				}
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		},"t2").start();
		
	}

问题照旧

ArrayBlockingQueue 取出null值问题_第1张图片

百思不得其解,问度娘也没有相关的文章,因为ArrayList是线程不安全的,所以怀疑 ArrayBlockingQueue 有没有可能是线程不安全的,没办法,翻看源码,的确是有lock的

ArrayBlockingQueue 取出null值问题_第2张图片

 这时看到了return false,想到何不 打印一下返回值看看

ArrayBlockingQueue 取出null值问题_第3张图片

通过打印内容,发现了问题,之所以取出null值是 因为 offer添加没有成功!

回过头来翻看代码,原来是时间设置的有问题

ArrayBlockingQueue 取出null值问题_第4张图片

线程 t2  每次循环取值前要先等待2秒钟,而线程 t1 每次执行offer插入的最大等待时长是1秒,这就导致了,队列是满的情况下,线程 t1 未能成功插入数据,所以只要让 线程 t1 每次执行offer插入的最大等待时长 大于2秒即可

修改 线程 t1 每次执行offer插入的最大等待时长为3秒,再次执行程序

ArrayBlockingQueue 取出null值问题_第5张图片

可以正常的存入取出数据了

 

后话,还是太马虎,沉下心来,夯实基础

 

你可能感兴趣的:(Java线程安全)