Is there a possibility to set priority to tasks which are executed by Executors? I've found some statements in JCIP about it's possible but I cannot find any example and I cannot find anything related in docs.
From JCIP:
An execution policy specifies the "what, where, when, and how" of task execution, including:
- ...
- In what order should tasks be executed (FIFO, LIFO, priority order)?
- ...
UPD: I realized that I asked not exactly what I wanted to ask. What I really wanted is:
How to use/emulate setting threads priority (i.e. what was thread.setPriority()) with executors framework?
It can be changed using the method setPriority() of class Thread. There are three static variables for thread priority in Java i.e. MIN_PRIORITY, MAX_PRIORITY and NORM_PRIORITY. The values of these variables are 1, 10 and 5 respectively.
If java process has normal priority it may not get system resources as much as it need. I can set this process priority to high from windows task manager by going to a process right click it and set priority as high.
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.
The idea here is to use a PriorityBlockingQueue in the executor. For this:
First you need to hold priority on your future:
class PriorityFuture<T> implements RunnableFuture<T> { private RunnableFuture<T> src; private int priority; public PriorityFuture(RunnableFuture<T> other, int priority) { this.src = other; this.priority = priority; } public int getPriority() { return priority; } public boolean cancel(boolean mayInterruptIfRunning) { return src.cancel(mayInterruptIfRunning); } public boolean isCancelled() { return src.isCancelled(); } public boolean isDone() { return src.isDone(); } public T get() throws InterruptedException, ExecutionException { return src.get(); } public T get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { return src.get(); } public void run() { src.run(); } } Next you need to define comparator that would correctly sort the priority futures:
class PriorityFutureComparator implements Comparator<Runnable> { public int compare(Runnable o1, Runnable o2) { if (o1 == null && o2 == null) return 0; else if (o1 == null) return -1; else if (o2 == null) return 1; else { int p1 = ((PriorityFuture<?>) o1).getPriority(); int p2 = ((PriorityFuture<?>) o2).getPriority(); return p1 > p2 ? 1 : (p1 == p2 ? 0 : -1); } } } Next let's assume we have a lengthy job like this:
class LenthyJob implements Callable<Long> { private int priority; public LenthyJob(int priority) { this.priority = priority; } public Long call() throws Exception { System.out.println("Executing: " + priority); long num = 1000000; for (int i = 0; i < 1000000; i++) { num *= Math.random() * 1000; num /= Math.random() * 1000; if (num == 0) num = 1000000; } return num; } public int getPriority() { return priority; } } Then in order to execute these jobs in priority the code will look like:
public class TestPQ { public static void main(String[] args) throws InterruptedException, ExecutionException { int nThreads = 2; int qInitialSize = 10; ExecutorService exec = new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new PriorityBlockingQueue<Runnable>(qInitialSize, new PriorityFutureComparator())) { protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) { RunnableFuture<T> newTaskFor = super.newTaskFor(callable); return new PriorityFuture<T>(newTaskFor, ((LenthyJob) callable).getPriority()); } }; for (int i = 0; i < 20; i++) { int priority = (int) (Math.random() * 100); System.out.println("Scheduling: " + priority); LenthyJob job = new LenthyJob(priority); exec.submit(job); } } } This is a lot of code but that's nearly the only way this can be accomplished.
On my machine the output is like the following:
Scheduling: 39 Scheduling: 90 Scheduling: 88 Executing: 39 Scheduling: 75 Executing: 90 Scheduling: 15 Scheduling: 2 Scheduling: 5 Scheduling: 24 Scheduling: 82 Scheduling: 81 Scheduling: 3 Scheduling: 23 Scheduling: 7 Scheduling: 40 Scheduling: 77 Scheduling: 49 Scheduling: 34 Scheduling: 22 Scheduling: 97 Scheduling: 33 Executing: 2 Executing: 3 Executing: 5 Executing: 7 Executing: 15 Executing: 22 Executing: 23 Executing: 24 Executing: 33 Executing: 34 Executing: 40 Executing: 49 Executing: 75 Executing: 77 Executing: 81 Executing: 82 Executing: 88 Executing: 97
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