I've searched a lot but couldn't find any solution. I use java thread pool in such way:
ExecutorService c = Executors.newFixedThreadPool(3);
for (int i = 0; i < 10; ++i) {
c.execute(new MyTask(i));
}
In such way Tasks are executed in consequent order (as in queue). But I need change "select next task" strategy. So I want assign to each task specify priority (it isn't thread priority) and execute tasks correspond to these priorities. So when executor have finished another task it chooses next task as task with maximum priority. It describes common problem. Maybe there is more simple approach which doesn't account priorities. It selects last added task as next to execute instead of first added. Roughly speaking FixedThreadPool use FIFO strategy. Can I use for example LIFO strategy?
You can use PriorityBlockingQueue to specify Queue to ThreadPoolExecutor.
public class PriorityExecutor extends ThreadPoolExecutor {
public PriorityExecutor(int corePoolSize, int maximumPoolSize,
long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) {
super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
}
//Utitlity method to create thread pool easily
public static ExecutorService newFixedThreadPool(int nThreads) {
return new PriorityExecutor(nThreads, nThreads, 0L,
TimeUnit.MILLISECONDS, new PriorityBlockingQueue<Runnable>());
}
//Submit with New comparable task
public Future<?> submit(Runnable task, int priority) {
return super.submit(new ComparableFutureTask(task, null, priority));
}
//execute with New comparable task
public void execute(Runnable command, int priority) {
super.execute(new ComparableFutureTask(command, null, priority));
}
}
Define ComparableFutureTask
to compare on Priority.
class ComparableFutureTask<T> extends FutureTask<T>
implements
Comparable<ComparableFutureTask<T>> {
volatile int priority = 0;
public ComparableFutureTask(Runnable runnable, T result, int priority) {
super(runnable, result);
this.priority = priority;
}
public ComparableFutureTask(Callable<T> callable, int priority) {
super(callable);
this.priority = priority;
}
@Override
public int compareTo(ComparableFutureTask<T> o) {
return Integer.valueOf(priority).compareTo(o.priority);
}
}
ThreadPoolExecutor constructor accepts BlockingQueue. You can pass queue as PriorityBlockingQueue. It does not make any grantee on ordering you need to pass custom comparators to maintain order.
static BlockingQueue<Task> queue=new PriorityBlockingQueue<Task>(MAXPOOL,new TaskComparator());
static ThreadPoolExecutor threadpool = new ThreadPoolExecutor(30, MAXPOOL,
MAXPOOL, TimeUnit.SECONDS, (PriorityBlockingQueue) queue, new mThreadFactory());
class TaskComparator implements Comparator<Task>{
public int compare(Task t1, Task t2){
//write you own logic to compare two task.
}
}
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