Java Executors: How to Set Task Priority

Java Executors: how can I set task priority?

Currently the only concrete implementations of the Executor interface are the ThreadPoolExecutor and the ScheduledThreadpoolExecutor

Instead of using the utility / factory class Executors, you should create an instance using a constructor.

You can pass a BlockingQueue to the constructors of the ThreadPoolExecutor.

One of the implementations of the BlockingQueue, the PriorityBlockingQueue lets you pass a Comparator to a constructor, that way enabling you to decide the order of execution.

How do I implement task prioritization using an ExecutorService in Java 5?

At first blush it would seem you could define an interface for your tasks that extends Runnable or Callable<T> and Comparable. Then wrap a ThreadPoolExecutor with a PriorityBlockingQueue as the queue, and only accept tasks that implement your interface.

Taking your comment into account, it looks like one option is to extend ThreadPoolExecutor, and override the submit() methods. Refer to AbstractExecutorService to see what the default ones look like; all they do is wrap the Runnable or Callable in a FutureTask and execute() it. I'd probably do this by writing a wrapper class that implements ExecutorService and delegates to an anonymous inner ThreadPoolExecutor. Wrap them in something that has your priority, so that your Comparator can get at it.

Handling priority in ThreadPools

If I understand correctly myScheduler (pool1) is used to schedule tasks and once time kicks in it submits tasks to executor (pool2).

given the question

What if subtasks have higher priority than scheduled tasks?

is not clear how you differentiate between them or what you really mean but what I understand is that subtasks are the scheduled tasks.

I think you should have some code like:

@Scheduled(cron="*/5 * * * * MON-FRI")
public void doSomething() {
executor.submit(aTaskThatRunsInParallelOrWhatYouCallASubTask);
}

where executor is the static object you are creating in. (shouldn't it be all caps and final ;))

as per its long name, what you are submitting to executor are "sub tasks" or the tasks the executor wakes up to submit. In this case your myScheduler will wake up always in time since what executes is non-blocking.

On the other hand, since you have a LinkedBlockingDeque which means executes in order, your executor might get backed up.

another Question:

Would they "jump" the queue and pause scheduled tasks in order to finish?

they won't jump, scheduler kicks in, submits new tasks and goes dormant again. Queue starts getting filled

next question:

Is there some way to force such behavior? Or tasks can't be paused when an ThreadPoolExecutor is already running them?

you could cancel the task all together, but you are going to keep track of all tasks submitted

you could catch a future

Future aFuture = executor.submit(aTaskThatRunsInParallelOrWhatYouCallASubTask);

and somehow you need to know that you actually want to cancel the task, you need to invoke

aFuture.cancel();

looks what you need is more involved, I would suggest look at JMS which is very mature or AKKA that might be easier to grasp.

ScheduledThreadPoolExecutor: How to priorize Tasks?

If I were you I'll have a single threaded ScheduledThreadPoolExecutor which posts to a ThreadPoolExecutor with a PriorityBlockingQueue. Not the most elegant, but it'll get the job done.

How to set the relative priority of scheduled thread?

This how I solved it:

ThreadGroup threadGroupCompute = new ThreadGroup("compute");
threadGroupCompute.setMaxPriority(Thread.NORM_PRIORITY);
threadGroupCompute.setDaemon(false);
ThreadFactory threadFacoryCompute = new ThreadFactory() {
long cnt = 0;
@Override
public Thread newThread(Runnable r) {
Thread t = new Thread(threadGroupCompute, r, "thread-" + threadGroupCompute.getName() + "-" + cnt++);
return t;
}
};
final ScheduledExecutorService executorCompute = new ScheduledThreadPoolExecutor(1, threadFacoryCompute);

// May be delayed by performance
executorCompute .scheduleAtFixedRate(new ComputeThread(), 0, 10, TimeUnit.MILLISECONDS);

And this 2 times. One with a ThreadGroup with priority set to Thread.NORM_PRIORITY, one with priority set to Thread.MAX_PRIORITY



Related Topics



Leave a reply



Submit