2013-04-25 30 views
6

Tôi có một số lượng lớn ảnh để tìm nạp từ máy chủ và tôi muốn tìm nạp một số hình ảnh có mức độ ưu tiên cao hơn so với những người khác nên tôi đã triển khai ThreadPoolExecutor của riêng mình trả về FutureTask thực hiện Comparable nhưng có vẻ như không hoạt động. Các tác vụ được xử lý nhiều hay ít theo thứ tự tôi thêm chúng vào hàng đợi. Tôi đã sửa lỗi số BlockingQueue trong số ThreadPoolExecutor của mình và phát hiện ra rằng khi tôi thêm Runnable của mình với mức độ ưu tiên cao hơn, nó sẽ không được dịch chuyển lên trên cùng của hàng đợi. Đây là mãThreadPoolExecutor được hỗ trợ bởi PriorityBlockingQueue dường như không hoạt động

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

} 

Và tôi thêm các nhiệm vụ cho các hồ bơi theo cách này:

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 cụ Comparable và khi tôi gỡ lỗi các phương pháp compareTo đang được gọi. Tôi đang làm gì sai? Cảm ơn

EDIT: dưới đây là đoạn code của Runnables tôi

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

Tôi khuyên bạn nên chia sẻ các phần liên quan của 'BitmapLoaderRunnable' trong trường hợp bạn có lỗi ở đó. –

+0

Bạn có chắc là có đủ Nhiệm vụ đang đợi trong hàng đợi của mình không, vì corePoolSize = 10? – mki

+0

Vâng để thử nó tôi đã đặt corePool và maxPool thành 1, và sau đó đặt một Thread.sleep (1000) trong mỗi Runnables của tôi, vẫn còn hành vi tương tự mặc dù ... Tôi đã chỉnh sửa câu hỏi để hiển thị Runnables của tôi – chopchop

Trả lời

8

Người đứng đầu của một PriorityQueue là yếu tố nhất. vì vậy nếu trước tiên bạn muốn ưu tiên cao nhất là , bạn cần đảo ngược so sánh của mình.

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

Ôi trời ơi, đã dành cả ngày hôm qua để cố gắng sửa nó, grrrrrrrrrrrrrr. Điều đó sẽ dạy tôi đọc đúng tài liệu từ bây giờ. Cám ơn rất nhiều! – chopchop

Các vấn đề liên quan