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 MyRunnables. 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