【问题标题】:How to have an unbound sortable queue utilized by a fixed amount of threads?如何让固定数量的线程使用未绑定的可排序队列?
【发布时间】:2012-07-11 10:23:35
【问题描述】:

请假设:

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 大小的池,并且可以按可比较或比较器排序。我只能使用LinkedBlockingQueue 实现 UNBOUND 队列,但这当然是不可排序的!

谢谢。

【问题讨论】:

  • A在一个内部类中,在DashboardHtmlExport里面。所以我需要一个DashboardHtmlExport 实例来调用new A(i)

标签: java threadpool priority-queue


【解决方案1】:

ThreadPoolExecutor 使用 newTaskFor() 方法将您提交的 Runnable 转换为 RunnableFuture,并将此 RunnableFuture 添加到队列中。因此,如果您想使用 PriorityQueue,您应该重写 newTaskFor() 方法以确保它创建的 RunnableFuture 实例具有可比性。

或者您也可以使用execute() 方法而不是submit() 方法来绕过任务创建。

【讨论】:

  • 谢谢。但为什么它只适用于前 2 次提交?!此外,如果cooldownbusyTime 多,它就可以工作!
  • @MuhammadGelbana:如果队列中的对象不超过一个,则不会进行比较,也不会出现错误。因此,您需要比消耗它们更快地生成它们,才会发生此错误。
  • 可能是因为队列在这些情况下不需要做任何比较,因为当任务加入队列时它是空的。
猜你喜欢
  • 2011-03-21
  • 1970-01-01
  • 1970-01-01
  • 2010-09-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多