我在自定义线程提取中使用PriorityBlockingQueue
时遇到问题,其中poll方法导致NullPointerException
。使用此设置时
int POOL_SIZE = 5;
int OVERHEAD_POOL_SIZE = 10;
long LIFE_TIME = 5000;
TimeUnit LIFE_TIME_UNIT = TimeUnit.MILLISECONDS;
与
new ThreadPoolExecutor(POOL_SIZE, OVERHEAD_POOL_SIZE,
LIFE_TIME, LIFE_TIME_UNIT, new PriorityBlockingQueue<Runnable>());
而不是Executors.newCachedThreadPool()
,我有时会遇到以下堆栈跟踪:
Exception in thread "pool-14-thread-3" java.lang.NullPointerException
at java.util.PriorityQueue.siftDownComparable(PriorityQueue.java:624)
at java.util.PriorityQueue.siftDown(PriorityQueue.java:614)
at java.util.PriorityQueue.poll(PriorityQueue.java:523)
at java.util.concurrent.PriorityBlockingQueue.take(PriorityBlockingQueue.java:225)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:957)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:917)
at java.lang.Thread.run(Thread.java:662)
基本上,我想按优先顺序在队列中命名Runnable
:
class MyRunnableFuture implements
RunnableFuture<Boolean>, Comparable<MyRunnableFuture>
有线的事情是:不总是抛出异常,但如果我在PriorityQueue.siftDownComparable
内设置断点,则发生异常的可能性更高。
有什么想法吗?我找到了其他人having the same problem,但没有人真正知道解决方案。在ThreadPool
中使用时,是否必须手动同步队列?我正在使用队列,因为我不想同步它。我理解这些描述好像队列已在内部同步了?谢谢你的回答!
答案 0 :(得分:0)
阅读以下评论后更新:所有问题都是由使用submit
代替execute
导致的,前者所有线程都包含在{{1}中在内部当然没有实现RunnableFuture
接口。这就是比较失败的原因。我被Comparable
分散了注意力,这是因为新的工作线程试图拉出之前无法插入的作业。 (线索:NullPointerException
没有插入新作业,因为抛出了PriorityBlockingQueue
。同时,ClassCastException
认为有新工作可用并警告下一个工作人员。工作人员提取了一个不存在的工作并抛出一个ThreadPoolExecutor
。NullPointerException
被吞下并记录在我的应用程序深处,我没有仔细跟踪,因为我试图找到{{1}的原因}。
为了完整起见,ClassCastException
的提交方法实际执行以下操作:
NullPointerException
感谢你们的帮助(在评论中!)。
PS:意思是错误。