I have a variation of the following code:
package com.test.package;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.PriorityBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class TestClass {
public static class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println("Called");
}
}
public void method() {
PriorityBlockingQueue<MyRunnable> queue = new PriorityBlockingQueue<MyRunnable>();
method2(queue);
}
public void method2(BlockingQueue<? extends Runnable> queue) {
System.out.println(queue);
// Getting error here because BlockingQueue<? extends Runnable> is not a
// subtype of BlockingQueue<Runnable>.
ThreadPoolExecutor threadPool = new ThreadPoolExecutor(200, 200, 0L,
TimeUnit.MILLISECONDS, queue);
}
}
And as you can see, my queue is not compatible with the ThreadPoolExecutor
constructor. Is there any way to work around this than cast my queue to (BlockingQueue<Runnable>)
? I obviously can't patch Java Standard Library.
No, and you shouldn't.
Your BlockingQueue<MyRunnable>
should, of course, only contain MyRunnable
s. But the ThreadPoolExecutor
can submit arbitrary Runnable
tasks to the queue you give it: see execute(Runnable command)
.
If that happens, you could have a non-MyRunnable
instance in your queue. You then try to poll from your reference of that queue (typed as a BlockingQueue<MyRunnable>
), and get a ClassCastException
.
Simple example:
PriorityBlockingQueue<MyRunnable> queue = new PriorityBlockingQueue<>();
ThreadPoolExecutor threadPool = new ThreadPoolExecutor(200, 200, 0L,
TimeUnit.MILLISECONDS, queue);
threadPool.execute(new WhateverRunnable());
MyRunnable myRunnable = queue.poll(); // this could throw ClassCastException
The above code will throw an exception if the queue.poll()
happens before the thread pool has had a chance to dequeue the WhateverRunnable
instance.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With