Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Specify task order execution in Java

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?

like image 641
Rustam Iuzmukhametov Avatar asked Oct 04 '12 07:10

Rustam Iuzmukhametov


2 Answers

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);
    }
  }
like image 181
Amit Deshpande Avatar answered Sep 28 '22 03:09

Amit Deshpande


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.
  }
}
like image 20
Subhrajyoti Majumder Avatar answered Sep 28 '22 04:09

Subhrajyoti Majumder