How to have an unbound sortable queue utilized by a fixed amount of threads?

走远了吗. 提交于 2019-12-13 16:05:56

问题


Please assume the following:

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));
    }
}

This produced the following error:

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

Why is this happening ?!

This only works if the busyTime is less that the cooldown time. Meaning that the queue can't handle more than 2 submitted tasks !!

Basically what I'm trying to do is to have a pool with UNBOUND size and sortable whether by comparable or a comparator. I can only achieve an UNBOUND queue using a LinkedBlockingQueue but that's of course not sortable !

Thank you.


回答1:


The ThreadPoolExecutor transforms the Runnable you submit into a RunnableFuture using the newTaskFor() method, and adds this RunnableFuture to the queue. So if you want to use a PriorityQueue, you should override the newTaskFor() method to make sure the RunnableFuture instances it creates are comparable.

Or you could also use the execute() method instead of the submit() method, to bypass the task creation.



来源:https://stackoverflow.com/questions/11430574/how-to-have-an-unbound-sortable-queue-utilized-by-a-fixed-amount-of-threads

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!