2

以下を想定してください。

public static void main(String[] args) {
    ThreadPoolExecutor pool = new ThreadPoolExecutor(0, 5, 1L, TimeUnit.SECONDS, new PriorityBlockingQueue<Runnable>());
    DashboardHtmlExport d = new DashboardHtmlExport();
    for (int i = 0; i < 40; i++) {
        System.out.println("Submitting: " + i);
        try {
            Thread.sleep(cooldown);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        pool.submit(d.new A(i));
    }
}

private class A implements Runnable, Comparable<A> {
    private int order;

    public A(int order) {
        this.order = order;
    }

    public void run() {
        try {
            Thread.sleep(busyTime);
        } catch (InterruptedException e) {
            System.out.println(e.getMessage());
        }
        System.out.println(new Date());
    }

    public int compareTo(A o) {
        return Integer.valueOf(o.order).compareTo(Integer.valueOf(order));
    }
}

これにより、次のエラーが発生しました。

Submitting: 0
Submitting: 1
Exception in thread "main" java.lang.ClassCastException: java.util.concurrent.FutureTask cannot be cast to java.lang.Comparable
    at java.util.PriorityQueue.siftUpComparable(PriorityQueue.java:578)
    at java.util.PriorityQueue.siftUp(PriorityQueue.java:574)
    at java.util.PriorityQueue.offer(PriorityQueue.java:274)
    at java.util.concurrent.PriorityBlockingQueue.offer(PriorityBlockingQueue.java:164)
    at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:653)
    at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:78)
    at com.skycomm.cth.pages.test.DashboardHtmlExport.main(DashboardHtmlExport.java:133)
Tue Jul 10 23:48:45 GMT+02:00 2012

なぜこうなった ?!

これは、 が時間よりbusyTime短い場合にのみ機能しcooldownます。つまり、キューは 2 つ以上のサブミットされたタスクを処理できません!!

基本的に私がやろうとしているのは、サイズがUNBOUNDで、比較可能なものでもコンパレーターでもソート可能なプールを持つことです。を使用してのみ UNBOUND キューを実現できますが、もちろんそれはsortableLinkedBlockingQueueではありません!

ありがとうございました。

4

1 に答える 1

11

ThreadPoolExecutor は、送信した Runnable をnewTaskFor()RunnableFutureメソッドを使用して変換し、この RunnableFuture をキューに追加します。したがって、PriorityQueue を使用する場合は、メソッドをオーバーライドして、作成されるインスタンスが比較可能であることを確認する必要があります。newTaskFor()RunnableFuture

または、execute()メソッドの代わりにメソッドを使用してsubmit()、タスクの作成をバイパスすることもできます。

于 2012-07-11T10:34:45.967 に答える