2013-04-25 2 views
6

У меня есть большое количество фотографий для извлечения с сервера, и я хочу получить некоторые снимки с более высоким приоритетом, чем другие, поэтому я внедрил свой собственный ThreadPoolExecutor, который возвращает FutureTask который реализует Comparable, но он не работает. Задачи более или менее обрабатываются в том порядке, в котором я добавляю их в очередь. Я отлаживал BlockingQueue моего ThreadPoolExecutor и узнал, что когда я добавляю свой Runnable с более высоким приоритетом, он не сдвигается полностью вверху очереди. Вот кодThreadPoolExecutor при поддержке PriorityBlockingQueue, похоже, не работает

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

} 

И добавить задачи в бассейн таким образом:

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

Мои BitmapLoaderRunnable орудия Comparable и когда я отладки метод compareTo вызывается. Что я делаю не так? Благодаря

EDIT: Ниже приведен код моего 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; 
     } 
    } 
+0

Я предлагаю вам поделиться соответствующими частями 'BitmapLoaderRunnable', если у вас есть ошибки. –

+0

Уверены ли, что в вашей очереди осталось много задач, так как corePoolSize = 10? – mki

+0

Да, чтобы попробовать, я установил corePool и maxPool в 1, а затем поместил Thread.sleep (1000) в каждую из моих Runnables, все еще такое же поведение, хотя ... Я отредактировал вопрос, чтобы показать мои Runnables – chopchop

ответ

8

Голова PriorityQueue является мере элемента. поэтому, если вы хотите, чтобы сначала приоритет , вам нужно обратить вспять свое сравнение.

@Override 
    public int compareTo(BitmapLoaderRunnable other) { 
     return other.bitmapToLoad.priority - this.bitmapToLoad.priority; 
    } 
+3

О, мой бог, весь вчера пытался исправить, grrrrrrrrrrrrrr. Это научит меня правильно читать документы с этого момента. Спасибо! – chopchop

Смежные вопросы