记录工作中遇到的问题,同时也希望可以帮助到有需要的朋友
ArrayBlockingQueue 相关知识网上很多帖子写的很好,还有丰富的demo,就不在此一一赘述了
这周在使用 ArrayBlockingQueue 时遇到一个问题,明明往队列中放( 用的offer(String e, long timeout, TimeUnit unit) )入了数据,但是取( 用的poll(long timeout, TimeUnit unit) )值的时候取到的是null值。
周末在家写了个测试demo
public static void main(String[] args) {
ArrayBlockingQueue<String> 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();
}
问题照旧
百思不得其解,问度娘也没有相关的文章,因为ArrayList是线程不安全的,所以怀疑 ArrayBlockingQueue 有没有可能是线程不安全的,没办法,翻看源码,的确是有lock的
这时看到了return false,想到何不 打印一下返回值看看
通过打印内容,发现了问题,之所以取出null值是 因为 offer添加没有成功!
回过头来翻看代码,原来是时间设置的有问题
线程 t2 每次循环取值前要先等待2秒钟,而线程 t1 每次执行offer插入的最大等待时长是1秒,这就导致了,队列是满的情况下,线程 t1 未能成功插入数据,所以只要让 线程 t1 每次执行offer插入的最大等待时长 大于2秒即可
修改 线程 t1 每次执行offer插入的最大等待时长为3秒,再次执行程序
可以正常的存入取出数据了
后话,还是太马虎,沉下心来,夯实基础