如何让固定数量的线程使用未绑定的可排序队列? [英] How to have an unbound sortable queue utilized by a fixed amount of threads?
问题描述
请假设:
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 个提交的任务!!
This only works if the busyTime
is less that the cooldown
time. Meaning that the queue can't handle more than 2 submitted tasks !!
基本上我想要做的是拥有一个 UNBOUND 大小的池,并且可以通过可比较或比较器进行排序.我只能使用 LinkedBlockingQueue
实现 UNBOUND 队列,但这当然不可排序!
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 !
谢谢.
推荐答案
ThreadPoolExecutor 使用 newTaskFor() 方法,并添加这个RunnableFuture 到队列中.因此,如果您想使用 PriorityQueue,您应该覆盖 newTaskFor()
方法以确保它创建的 RunnableFuture
实例具有可比性.
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.
或者你也可以使用 execute()
方法代替 submit()
方法,绕过任务创建.
Or you could also use the execute()
method instead of the submit()
method, to bypass the task creation.
这篇关于如何让固定数量的线程使用未绑定的可排序队列?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!