I have a Java component that does some super complicated business logic, some of it parallelized and threads executing subtasks are pooled. Now each request to this component can have some priority thats is mapped in some way to thread priority. A the the beginning of execution i can assign a proper priority to executing thread. The problematic part is to pass priority to each threads executing subtasks. I know that spawning a new child thread will accomplish this because child threads inherit priority of parent threads but i would like to take advantage of thread pooling. An the question:
- Is there a way to ensure that each thread in execution path has proper priority ?
- How can i monitor threads priority at each stage of execution, of course i don't want to hard-code any tracing code? On thing that came into my mind is to write some tracing script in BTrace
You want to use thread pools, which would be made useless if you had to spawn new threads just to set job priority.
I think you want each job (not thread) to have a different priority. If that is the case, let's look at a constructor signature for
ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue)
- Instead of using one of the recommended
Executors' factory methods to construct your thread pool, do
new ThreadPoolExecutor(...)yourself, using one of its numerous signatures.
Executors.defaultThreadFactoryinto this constructor (the signature I listed above does this internally). This will do automatic thread priority assignment as it creates the threads (for a fixed size thread pool, that should happen just once per thread, at app start).
- Pass a
PriorityBlockingQueue<Runnable>into this constructor. This is the queue which will allow you to prioritise jobs (not threads).
Runnableinto an abstract
PriorityRunnableclass which allows get/set of priority. These represent the jobs, so when you want to make a new job, simply extend this and custom-set the priority as appropriate for that job.
Comparatorto perform ordering on elements as you insert them into the queue, and let that queue use it.
- Add your jobs to the queue.
Note that if you have your queue already populated by this time (eg. for batch processing apps), you can call
executor.prestartCoreThread(n) at once after construction.
It's all pretty simple, and takes surprisingly few lines of code to set up.
EDIT: Just found the same approach being discussed over at Java Ranch.