When I create ExecutorService with below code in JAVA,can someone explain how the ExecutorService works ?
ExecutorService executor = Executors.newFixedThreadPool(400);
for (int i = 0; i < 500; i++) {
Runnable worker = new MyRunnable(10000000L + i);
executor.execute(worker);
}
I believe that there will be a single Queue of work and my for loop will add 500 Runnable tasks to this queue. Now the ExecutorService has been created with a Thread Pool of 400 threads.
So of those 500 tasks in the queue, the 400 threads in the ExecutorService will execute this 400 tasks at a time, and the remaining as slots are freed up?
Am I correct in my understanding ?
JavaDoc newFixedThreadPool
Creates a thread pool that reuses a fixed number of threads operating
off a shared unbounded queue. At any point, at most nThreads threads
will be active processing tasks. If additional tasks are submitted
when all threads are active, they will wait in the queue until a
thread is available. If any thread terminates due to a failure during
execution prior to shutdown, a new one will take its place if needed
to execute subsequent tasks. The threads in the pool will exist until
it is explicitly shutdown.
If tasks are more than number of processing threads, the tasks which haven't been picked up by threads will wait. Once the thread completes one task, it will pick-up one more waiting task.
But these thread pools (other than ForkJoinPool) are not efficient in stealing worker thread tasks.
Assume that one thread is backlog of 10 tasks to be executed and it's running first task. At that same time, some other thread in pool is idle. In this scenario, once the task is allocated a Thread, only that thread will execute the task even though other threads are idle.
ForkJoinPool differs from other kinds of ExecutorService mainly by virtue of employing work-stealing: all threads in the pool attempt to find and execute tasks submitted to the pool and/or created by other active tasks (eventually blocking waiting for work if none exist)
One more new API has been added in Java 8.
public static ExecutorService newWorkStealingPool()
Creates a work-stealing thread pool using all available processors as its target parallelism level.
Relate SE question : ThreadPoolExecutor vs ForkJoinPool: stealing subtasks
Related
Please note that I usually ask a question after googling for more than 20 times about the issue. But I can't still understand it. So I need your help.
Basically, I don't understand the exact usage of newFixedThreadPool
Does newFixedThreadPool(10) mean having ten different threads? Or does it mean it can have 10 of the same threads? or the both?
I executed with submit() methods more than 20 times and it's working.
Does submit() print a value? Or are you putting threads in the ExecutorService?
Briefly, tasks are small units of code that could be executed in parallel (code sections). The threads (in a thread pool) are what execute them. You can think of the threads like workers and the tasks like jobs. Jobs can be done in parallel, and workers can work in parallel. Workers work on jobs.
So, to answer your questions:
newFixedThreadPool(int nThreads) creates a thread pool of nThread threads that operate on the same input queue. nThreads is the maximum number of threads that can be running at any given time. Each thread can run a different task. With your example, you can be running up to 10 tasks at the same time. (The documentation can be found here with credit to #hovercraft-full-of-eels)
submit() pushes the given task into an event queue that is shared by the threads in the thread pool. Once a thread is available, it will take a task from the front of the queue and execute it. It shouldn't print anything, unless the Runnable you pass it has a print statement in it. However, the print statement may not be printed right when you submit the task! It will print once a thread is executing that particular task. (The documentation can be found here)
Just refer java docs or JAVA API's description rather than googling it.
For your questions I have below comments .
Question 1 ->
ExecutorService executorService = Executors.newFixedThreadPool(10);
First an ExecutorService is created using the Executors newFixedThreadPool() factory method. This creates a thread pool with 10 threads executing tasks.
Executors.newFixedThreadPool API creates, a thread pool that reuses a fixed number of threads and these threads work on a s***hared unbounded queue***.
At any point, at most nThreads threads will be active processing tasks.
If additional tasks are submitted when all threads are active, they will wait in the queue until a thread is available.
If any thread terminates due to a failure during execution prior to shutdown, a new one will take its place if needed to execute subsequent tasks. The threads in the pool will exist until it is explicitly SHUTDOWN.
After submitting even 20 tasks ,it worked with this thread pool.
Internally it calls below line of codes .
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue());
}
Question 2- > Submits a Runnable task for execution in Queue and it can also return an Object of type Future Object representing task. we can use Future's get method to check whether submitted task has successfully completed or not because it will return null upon successful completion.
I am fetching messages from Kafka and processing them using Executor service similar to below. I am not calling executorService.shutdown(). I have occasionally been seeing heapSize exception , but not sure if this could be one of the causes. How do the unused Runnable instances get removed after completion? Should I do anything specific to explicitly make it eligible for GC?
public class Consumer implements CommandLineRunner{
ExecutorService executorService;
executorService = Executors.newFixedThreadPool(50)
executorService.submit(runnable);
}
}
From documentation for Executors.newFixedThreadPool:
Creates a thread pool that reuses a fixed number of threads operating
off a shared unbounded queue. At any point, at most nThreads threads
will be active processing tasks. If additional tasks are submitted
when all threads are active, they will wait in the queue until a
thread is available. If any thread terminates due to a failure during
execution prior to shutdown, a new one will take its place if needed
to execute subsequent tasks. The threads in the pool will exist until
it is explicitly shutdown.
For given example there will be at most 50 threads active in the thread pool and they are released when you call shutdown method.
If you do not keep references to your Runnables they will be GCed when Executor is done with them. If you get out of memory exceptions this can be due to queued Runnables in cases when executor can not keep up with the work submitted to him.
EDIT: Also out of memory exceptions can happen if your tasks take a lot of memory (obviously).
How to i implement such a function ?
I have a dynamic queue which gets filled at unknown times with runnables, which have to be executed. The ExecutorService should only start a limited amount of threads, when the maximum thread size is reached, it should stop executing more threads, until one thread finishes, then the next task should be executed.
So far i came across this:
ExecutorService executor = new ThreadPoolExecutor(20, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
databaseConnectionQueue);
The ExecutorService is created before the queue is filled, and should stay alive until the queue is deleted, not when its empty, because this can happen. Can anybody help me ?
ThreadPoolExecutor will will not shutdown when it is empty. From the JavaDoc:
A pool that is no longer referenced in a program AND has no remaining
threads will be shutdown automatically.
I believe you should use FixedThreadPool (Executors.newFixedThreadPool)
As per javadoc [Executors.newFixedThreadPool]
Creates a thread pool that reuses a fixed number of threads operating
off a shared unbounded queue. At any point, at most nThreads threads
will be active processing tasks. If additional tasks are submitted
when all threads are active, they will wait in the queue until a
thread is available. If any thread terminates due to a failure during
execution prior to shutdown, a new one will take its place if needed
to execute subsequent tasks. The threads in the pool will exist until
it is explicitly shutdown.
Hope it helps. Thanks.
I have 4-5 worker threads processing large message queue. And I also have another piece of code which runs using 2-3 workers. I wanted to block all other workers when large message queue is being processed.
I am using JDK 6, and Jms
EDITED:
Queue process workers never terminated. They blocked on queue when no message. These workers are managed by executor thread pool.If I use read-write lock, one of these workers will get blocked too.
Also, if used cyclic barrier then I have to terminate threads in order to relase the blocking second process. Since workers are managed by thread pool, it is not assured that all workers will be busy processing messages.
Let me know,
final ExecutorService executor = getExecutorManager().getExecutor();
for (int i = 0; i < threadPoolSize; i++) {
executor.submit(new MessageWorker(qConn));
}
Following is second module, where i want all workers to be blocked while queue processors worker threads are working.
final ExecutorService executor = getExecutorManager().getExecutor();
for (int i = 0; i < threadPoolSize; i++) {
executor.submit(new DbUpdateWorker());
}
You need to use CyclicBarrier.
A synchronization aid that allows a set of threads to all wait for each other to reach a common barrier point. CyclicBarriers are useful in programs involving a fixed sized party of threads that must occasionally wait for each other. The barrier is called cyclic because it can be re-used after the waiting threads are released.
Use as:
CyclicBarrier barrier = new CyclicBarrier(numWorkers, runnable);
Where runnable is a Runnable that you want to call when your worker threads are finished. Each thread calls barrier.await() when it's complete.
I would like to implement a piece of software that will make sure 10 threads running the same class all the time
All threads will terminate let's say after a certain number of seconds at random, but then, I want to make sure once they're terminated, they're replaced instantly by newly created threads.
Would you know if there's any library available?
Many thanks,
Vlad
Rather you use Thread Pool. Java Executor framework provides it.
ExecutorService executor = Executors.newFixedThreadPool(10);
ExecutorService executorPool = Executors.newFixedThreadPool(noOfThreads);
public static ExecutorService newFixedThreadPool(int nThreads)
Creates a thread pool that reuses a fixed set of threads operating off a
shared unbounded queue. If any thread terminates due to a failure during execution prior to shutdown, a new one will take its place if needed to execute subsequent tasks.
Parameters:
nThreads - the number of threads in the pool
Returns:
the newly created thread pool