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と、例外が発生する可能性が高くなります。

何か案は?他の人が同じ問題を抱えているのを見つけましたが、誰も本当に解決策を知りませんでした. で使用する場合、キューを手動で同期する必要がありThreadPoolますか? 同期したくないので、キューを使用しています。キューがすでに内部で同期されているかのように説明を理解しましたか? 回答ありがとうございます。

4

1 に答える 1

0

以下のコメントを読んだ後に更新されましたsubmit: すべての問題は、前者の where の代わりに使用することによって引き起こされました。すべてのスレッドは、もちろんインターフェイスを実装していない内部でexecuteラップされています。これが比較に失敗した理由です。以前は挿入できなかったジョブを新しいワーカー スレッドがプルしようとしているときに発生するに気が散ってしまいました。(手がかり:は a がスローされるため、新しいジョブを挿入しません。同時に、 は利用可能な新しいジョブがあると考え、次のワーカーに警告します。ワーカーは存在しないジョブをプルし、 をスローします。飲み込まれてログに記録されます。アプリケーションの奥深くで、理由を見つけようとしたため、これを十分に注意深く追跡しませんでしたRunnableFutureComparableNullPointerExceptionPriorityBlockingQueueClassCastExceptionThreadPoolExecutorNullPointerExceptionClassCastExceptionNullPointerException.

完全を期すために、 の submit メソッドは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 に答える