For some proposes, I need to create an Executor which has always one same thread.
Executors.newFixedThreadPool(1);
Executors.newScheduledThreadPool(1);
Above examples create one thread pool but when work is done then the thread will be ended and again created a new one if a new task is passed to the executor.
So I figured out something like this:
new ThreadPoolExecutor(1,1,Long.MAX_VALUE, TimeUnit.DAYS, new LinkedBlockingQueue<>());
it seems that works but I have doubts if it's the right approach. Can someone show a better/correct way?
Executors.newSingleThreadExecutor();
From the documentation (emphasis mine):
Creates an Executor that uses a single worker thread operating off an unbounded queue. (Note however that if this single thread terminates due to a failure during execution prior to shutdown, a new one will take its place if needed to execute subsequent tasks.) Tasks are guaranteed to execute sequentially, and no more than one task will be active at any given time. Unlike the otherwise equivalent newFixedThreadPool(1) the returned executor is guaranteed not to be reconfigurable to use additional threads.
Related
CompletableFuture.runAsync documentation states:
Returns a new CompletableFuture that is asynchronously completed by a task running in the ForkJoinPool.commonPool() after it runs the given action.
However, as far as I can tell, runAsync only submits a task to ForkJoinPool.commonPool() when ForkJoinPool.getCommonPoolParallelism() > 1. If not, it manually creates a new Thread for each submitted task.
Why exactly is this the case?
Yes, if ForkJoinPool parallelism level is less than 2, then new thread is created for every task here
All async methods without an explicit Executor argument are performed using the ForkJoinPool.commonPool() (unless it does not support a parallelism level of at least two, in which case, a new Thread is created to run each task).
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 currently need to create multiple threadpools. Each threadpool is a single threaded threadpool.
I assign tasks to each threadpool based upon a condition. So I need to maintain track of threadpools.
How can I do that?
Can I create an array of threadpools?
ExecutorService executor = Executors.newSingleThreadExecutor();
This is how we create 1 threadpool. Now I want to create 5 threadpools.
ExecutorService[] executor;
for(int i=0;i<5;i++){
executor[i]= Executors.newSingleThreadExecutor();
}
Is this ok? Is this right syntax? If not, can you suggest a way to do it?
In your scenario, I believe it is possible to use just one single thread Executor since according to the documentation:
Creates an Executor that uses a single worker thread operating off an
unbounded queue. (Note however that if this single thread terminates
due to a failure during execution prior to shutdown, a new one will
take its place if needed to execute subsequent tasks.) Tasks are
guaranteed to execute sequentially, and no more than one task will be
active at any given time. Unlike the otherwise equivalent
newFixedThreadPool(1) the returned executor is guaranteed not to be
reconfigurable to use additional threads.
Therefore with multiple input from multiple companies, the queue of the Executor will look like:
[Company1Task1, Company2Task1, Company1Task2, Company3Task1,
Company1Task3, ...]
And the Executor will process it sequentially.
I'm new to java concurrency so this may be a question already answered many time over or too obvious that I maybe missing something.
I am running as task like so:
Executors.newSingleThreadExecutor().execute(task)
My question is when its comes to end of executing the run method of task why does it not exit or why is the thread still alive? My understanding was once a threads run() completes the thread is no more and ceases to exist, right?
newSingleThreadExecutor returns an ExecutorService which uses a single thread - it can still execute multiple tasks. It doesn't exit because you may want to supply more tasks.
You can use:
ExecutorService service = Executors.newSingleThreadExecutor();
service.execute(task);
service.shutdown();
to shut it down after the task has executed.
the thread remains alive because its lifecycle is not tied to that of the tasks assigned to the executor; take a look at:
javadoc for Executors.newSingleThreadExecutor
you'll find that internally, the returned ExecutorService uses a single thread to sequentially run as many tasks as you assign to it, potentially instantiating a new thread if one of your tasks kills the original one.
Well title says it, what is the difference between Executors.newSingleThreadExecutor().execute(command) and new Thread(command).start();
Behaviourally, pretty much nothing.
However, once you have an Executor instance, you can submit multiple tasks to it, and have them executed one after another. You can't do that simply with a raw Thread.
One noticeable difference, is when you run new Thread(someRunnable).start(); when the runnable is finished the thread will die quietly.
The Executor though will persist until you shut it down. So running Executors.newSingleThreadExecutor().execute(command) When you think your application or the JVM may be finished the Executor may still be running in a background thread.
With Executor.execute, if an Error or RuntimeException is thrown in the Executor it will be swallowed silently, while the new Thread() will print it to System.err.
There can be many differences, but I will show you one difference which I found very important to understand:
public void sendEventSingleThreadExecutor(Event e){
Executor.singleThreadExecutor().execute(()->{//send the event here})
}
Now, even if you call sendEventSingleThreadExecutor method 10 times, it will use only a single thread to send them. It will not create a new thread every time. Which means that the events will be sent sequentially or synchronously!
You can read more from here:
Now see the below example with new thread
public void sendEventThread(Event e){
Thread(//send the event here).start();
}
If you call it 10 times, it will create 10 new threads. Which means, the executions will be asynchronous! And it could be dangerous, it can create a lot of threads depending on how many times you call sendEventThread functions.
Please note that, the code are only for demonstration purpose, it might have syntax error!
If you find any wrong description here, I will be happy to be corrected.
Some more information from here
newSingleThreadExecutor. A single-threaded executor creates a single
worker thread to process tasks, replacing it if it dies unexpectedly.
Tasks are guaranteed to be processed sequentially according to the
order imposed by the task queue (FIFO, LIFO, priority order).[4]
[4] Single-threaded executors also provide sufficient internal
synchronization to guarantee that any memory writes made by tasks are
visible to subsequent tasks; this means that objects can be safely
confined to the “task thread” even though that thread may be replaced
with another from time to time.
I prefer to use ExecutorService or ThreadPoolExecutor even for single digit threads. They offer more flexibility.
Have a look at ExecutorService & ThreadPoolExecutor sections in related SE questions :
java Fork/Join pool, ExecutorService and CountDownLatch
Java's Fork/Join vs ExecutorService - when to use which?
Assume that you have started with your own thread instead of ExecutorService. In future, if there is a need for supporting multiple threads, ExecutorService or ThreadPoolExecutor will offer better control and flexibility for you. You can fine-tune required number of parameters in these below APIs.
ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime,
TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory,
RejectedExecutionHandler handler)
Executors.newSingleThreadExecutor().execute(command) will reuse previously constructed thread, it will not created new thread as in case of new Thread(). If the thread that have not been used for sixty seconds are terminated, It's a kind of pool which contains a single thread which make its equivalent newFixedThreadPool(1).