[英]ThreadPoolExecutor backed by PriorityBlockingQueue doesn't seem to work
I have a large number of pictures to fetch from a server, and I want to fetch some pictures with higher priority than others so I've implemented my own ThreadPoolExecutor
that returns a FutureTask
that implements Comparable
but it doesn't seem to work. 我有很多图片要从服务器上获取,我想要获取一些优先级高于其他图片的图片,所以我实现了自己的
ThreadPoolExecutor
,它返回一个实现Comparable
的FutureTask
,但它似乎不起作用。 The tasks are more or less processed in the order I add them to the queue. 这些任务或多或少按照我将它们添加到队列的顺序进行处理。 I've debugged the
BlockingQueue
of my ThreadPoolExecutor
and found out that when I add my Runnable
with a higher priority, it is not shifted all the way up at the top of the queue. 我调试了
ThreadPoolExecutor
的BlockingQueue
,发现当我添加具有更高优先级的Runnable
时,它不会在队列顶部一直向上移动。 Here is the code 这是代码
public class PriorityThreadPoolExecutor extends ThreadPoolExecutor {
public PriorityThreadPoolExecutor(int corePoolSize, int maximumPoolSize,
long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) {
super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
}
protected <T> RunnableFuture<T> newTaskForValue(Runnable runnable, T value) {
return new ComparableFutureTask<T>(runnable, value);
}
protected class ComparableFutureTask<T>
extends FutureTask<T> implements Comparable<ComparableFutureTask<T>> {
private Object object;
public ComparableFutureTask(Runnable runnable, T result) {
super(runnable, result);
object = runnable;
}
@Override
@SuppressWarnings({ "unchecked", "rawtypes" })
public int compareTo(ComparableFutureTask<T> o) {
if (this == o) {
return 0;
}
if (o == null) {
return -1; // this has higher priority than null
}
if (object != null && o.object != null) {
if (object.getClass().equals(o.object.getClass())) {
if (object instanceof Comparable) {
return ((Comparable) object).compareTo(o.object);
}
}
}
return 0;
}
}
}
And I add the tasks to the pool in this way: 我以这种方式将任务添加到池中:
public BitmapLoader(Context context){
mThreadPoolExecutor = new PriorityThreadPoolExecutor(10, Integer.MAX_VALUE,//corepool and maxpool
1L, TimeUnit.SECONDS,//keep alive idle threads
new PriorityBlockingQueue<Runnable>());//priority queue for jobs
}
public void queuePhoto(String url, ImageView imageView, int priority) {
BitmapToLoad p = new BitmapToLoad(url, imageView, priority);
final RunnableFuture<Object> futureTask =
mThreadPoolExecutor.newTaskForValue(new BitmapLoaderRunnable(p), null);
Log.d("BitmapLoader", "Scheduling job with priority " + priority);
mThreadPoolExecutor.execute(futureTask);
}
My BitmapLoaderRunnable
implements Comparable
and when I debug the compareTo
method is being called. 我的
BitmapLoaderRunnable
实现了Comparable
,当我调试时,正在调用compareTo
方法。 What am I doing wrong? 我究竟做错了什么? Thanks
谢谢
EDIT: below is the code of my runnables 编辑:下面是我的runnables的代码
private class BitmapLoaderRunnable implements Runnable, Comparable<BitmapLoaderRunnable> {
private BitmapToLoad bitmapToLoad;
public BitmapLoaderRunnable(BitmapToLoad bitmap) {
this.bitmapToLoad = bitmap;
}
@Override
public void run() {
try{
if(imageViewReused(bitmapToLoad))
return;
Thread.sleep(1000);
Bitmap bmp = getBitmap(bitmapToLoad.url);
BitmapCache.put(bitmapToLoad.url, bmp);
if(imageViewReused(bitmapToLoad))
return;
BitmapDisplayer bd = new BitmapDisplayer(bmp, bitmapToLoad);
mHandler.post(bd);
} catch(Throwable th){
th.printStackTrace();
}
}
@Override
public int compareTo(BitmapLoaderRunnable other) {
return this.bitmapToLoad.priority - other.bitmapToLoad.priority;
}
}
The head of a PriorityQueue
is the least element. PriorityQueue
的头部是最少的元素。 so if you want the highest priority first, you need to reverse your comparison. 因此,如果您想先获得最高优先级,则需要撤消比较。
@Override
public int compareTo(BitmapLoaderRunnable other) {
return other.bitmapToLoad.priority - this.bitmapToLoad.priority;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.