2013-04-25 32 views
6

我有大量的圖片從服務器獲取,我想獲取一些圖片比其他人更高的優先級,所以我實現了我自己的ThreadPoolExecutor,返回FutureTask實施Comparable,但它似乎沒有工作。這些任務或多或少地按照我將它們添加到隊列中的順序進行處理。我調試了我的ThreadPoolExecutorBlockingQueue,發現當我添加具有更高優先級的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方法。我究竟做錯了什麼?由於

編輯:下面是我的可運行

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'的相關部分。 – 2013-04-25 11:07:41

+0

您確定在您的隊列中有足夠的任務正在等待,因爲corePoolSize = 10? – mki 2013-04-25 11:33:48

+0

是的,所以嘗試它我已經將corePool和maxPool設置爲1,然後在每個Runnables中放置一個Thread.sleep(1000),儘管如此,仍然有相同的行爲...我編輯了問題以顯示我的Runnables – chopchop 2013-04-25 11:53:54

回答

8

的代碼PriorityQueue的頭是至少元素。所以如果你想首先優先最高,你需要扭轉你的比較。

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

噢,我的上帝,花了整個昨天試圖修復它,grrrrrrrrrrrrrr。這將教會我從現在開始正確閱讀文檔。非常感謝! – chopchop 2013-04-26 02:31:43

相關問題