2

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按优先级对队列中的 s 进行排序:

class MyRunnableFuture implements 
        RunnableFuture<Boolean>, Comparable<MyRunnableFuture>

连线的事情是:异常并不总是被抛出,但如果我在里面设置一个断点PriorityQueue.siftDownComparable,发生异常的机会就更高了。

有任何想法吗?我发现其他人也有同样的问题,但没有人真正知道解决方案。在 a 中使用时是否必须手动同步队列ThreadPool?我正在使用队列,因为我不想同步它。我理解描述好像队列已经在内部同步了?感谢您的任何回答!

4

1 回答 1

0

阅读以下评论后更新:所有麻烦都是由使用submit而不是execute前者引起的,所有线程都包装在RunnableFuture内部当然不实现Comparable接口。这就是比较失败的原因。NullPointerException当一个新的工作线程试图拉动以前无法插入的作业时,我被分心了。(线索:PriorityBlockingQueue没有插入新工作,因为 aClassCastException被抛出。同时,ThreadPoolExecutor认为有新工作可用并提醒下一个工人。工人拉出一个不存在的工作并抛出 a NullPointerExceptionClassCastException被吞下并记录在我的应用程序深处,我没有足够仔细地追踪这一点,因为我试图找到原因NullPointerException.

为了完整起见,ThreadPoolExecutor实际的提交方法如下:

public Future<?> submit(Runnable task) {
    if (task == null) throw new NullPointerException();
    RunnableFuture<Void> ftask = newTaskFor(task, null);
    execute(ftask);
    return ftask;
}

感谢你们的帮助(在评论中!)。

PS:平均错误。

于 2013-10-08T15:14:10.083 回答