6

I'm trying to make an ThreadPoolExecutor with priority. So I define a

private static ThreadPoolExecutor threadpool = new ThreadPoolExecutor(30, MAXPOOL,  MAXPOOL, TimeUnit.SECONDS,  
     queue, new mThreadFactory());

So the key is the queue reference now. But when I declare :

static PriorityBlockingQueue<mDownloadThread> queue=new PriorityBlockingQueue<mDownloadThread>(MAXPOOL,new DownloadThreadComparator());

The compiler gives an error in the first line: The constructor ThreadPoolExecutor(int, int, int, TimeUnit, PriorityBlockingQueue, FileAccess.mThreadFactory) is undefined with a single quickfix: Change type of 'queue' to BlockingQueue. Can you help me to understand whats the problem?

Thanks

Additional Info:

For comparing the runnables I implementd the following class

class mDownloadThread implements Runnable{      
    private Runnable mRunnable;     
    private int priority;       
    mDownloadThread(Runnable runnable){
        mRunnable=runnable;         
    }

    @Override
    public void run() {
        mRunnable.run();        
    }

    public int getPriority() {
        return priority;
    }

    public void setPriority(int priority) {
        this.priority = priority;
    }       
}

The comparator:

class DownloadThreadComparator implements Comparator<mDownloadThread>{
    @Override
    public int compare(mDownloadThread arg0, mDownloadThread arg1) {

    if (arg0==null && arg1==null){
        return 0;
    } else if (arg0==null){
        return -1;
    } else if (arg1==null){
        return 1;
    }
    return arg0.getPriority()-arg1.getPriority();

    }

}
Addev
  • 31,819
  • 51
  • 183
  • 302

2 Answers2

6

ThreadPoolExecutor constructor accepts BlockingQueue<Runnable> and not BlockingQueue<? extends Runnable>, thus you can't pass to it PriorityBlockingQueue<mDownloadThread> instance.

You can change type of queue to PriorityBlockingQueue<Runnable>, but in that case you won't be able to implement Comparator<mDownloadThread> without casting inside the compare method.

The other solution is to bypass generic type-checking but it would be your responsibility to submit only instances of mDownloadThread to execute method:

static ThreadPoolExecutor threadpool = new ThreadPoolExecutor(30, MAXPOOL, 
        MAXPOOL, TimeUnit.SECONDS, (PriorityBlockingQueue) queue, new mThreadFactory());
Volo
  • 28,673
  • 12
  • 97
  • 125
4

The problem is that ThreadPoolExecutor is expecting a BlockingQueue<Runnable> and you are passing a PriorityBlockingQueue<mDownloadThread>. The PriorityBlockingQueue implements BlockingQueue so that is not the problem. The problem is the Runnable. You cannot pass a generic type of mDownloadThread where Runnable was expected.

Fix is the following:

static PriorityBlockingQueue<Runnable> queue=new PriorityBlockingQueue<Runnable>(MAXPOOL,new DownloadThreadComparator());

&&

class DownloadThreadComparator implements Comparator<Runnable>{  

If ThreadPoolExecutor were written to accept a BlockingQueue<? extends Runnable> what you have would work.

John B
  • 32,493
  • 6
  • 77
  • 98
  • mDownloadThread implements Runnable also. so it shouldn't be a problem right? – Addev Oct 17 '11 at 11:15
  • No. Just like you can't pass a `List` into a `List` – John B Oct 17 '11 at 11:16
  • Doing this passes instances of FutureTask into the Comparator. This is legal because it extends from Runnable. You can't get at the attributes necessary for a comparison of the object in question, though. Real pain in the butt. – Mike Feb 17 '12 at 22:13