2

I want to instantiate a new java ThreadPoolExecutor with this piece of code:

public class ImageList {
    private LinkedBlockingQueue<Image> list;
    private final ThreadPoolExecutor executor;

    public ImageList() {
        executor = new ThreadPoolExecutor(2, 4, 100, TimeUnit.SECONDS, list);
    }
}

Where Image has the following header:

public class Image implements Runnable, Serializable

However, Java complains that a constructor for the type BlockingQueue<Runnable> was not found. What am I doing wrong?

aufziehvogel
  • 7,167
  • 5
  • 34
  • 56
  • 1
    Inheritance in Generics is little different from Inheritance in classes. You need to use wildcards http://docs.oracle.com/javase/tutorial/java/generics/inheritance.html – kosa Jul 13 '12 at 14:52
  • Generics and polymorphism: http://stackoverflow.com/questions/2745265/is-listdog-a-subclass-of-listanimal-why-arent-javas-generics-implicit – assylias Jul 13 '12 at 14:56

1 Answers1

4

The constructor expects a BlockingQueue<Runnable>. You pass it a BlockingQueue<Image>.

A BlockingQueue<Image> is not a BlockingQueue<Runnable>. Indeed, you may store any kind of Runnable in a BlockingQueue<Runnable>, but you may only store Image instances in a BlockingQueue<Image>.

If it were, you could do the following:

BlockingQueue<Image> list = new BlockingQueue<Image>();
BlockingQueue<Runnable> list2 = list1;
list2.add(new Runnable() {...});

and boom! your BlockingQueue<Image> would contain something other than an Image.

JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
  • Wouldn't you be able to do `BlockingQueue extends Runnable>`? – jn1kk Jul 13 '12 at 15:42
  • 1
    No. The thread pool needs a BlockingQueue, to be able to store the Runnable instances it creates in the queue. BlockingQueue extends Runnable> means: BlockingQueue of some unknown subclass which is or extends Runnable. You can't store anything into such a queue. – JB Nizet Jul 13 '12 at 16:58
  • Doesn't `Image` implement ("extends") `Runnable` though? So you could put `Image`s into `BlockingQueue extends Runnable>`, or am I wrong (or misunderstanding OP's question)? – jn1kk Jul 13 '12 at 17:25
  • You're wrong. Read my answer: it should answer your question: `BlockingQueue extends Runnable> list = new BlockingQueue();BlockingQueue list2 = list1;list2.add(new Runnable() {...});// boom!` – JB Nizet Jul 13 '12 at 17:35
  • You are right. That would only work if you could change the constructor. Constructor expects a queue of `Runnable`. But queue of `Runnable` is not a queue of `Image`. Thanks. – jn1kk Jul 13 '12 at 17:45
  • Wildcarded instances inherently have issues with adding things to them as @JB Niznet stated. The ? syntax does not mean any instance of Runnable. It indicates that it's a homogenious instance that's type compatible. So BlockingQueue extends Runnable> doesn't mean that i have a queue of anything that extends runnable. It means I have a queue who components are all of the same type, and that type extends runnable. This is why the .add() method on such objects gives you compile errors. The compiler can't tell what the actual type will be. – Matt Jul 16 '12 at 13:20