Java FixedThreadPool waiting thread context switch - java

I have 3 fixedThreadPools in my application with size of 20 each.
I submit the tasks in pools but they are few sometimes say 5 task in each pool1 ,pool2 ,pool 3 so I have 15 threads from each pool sitting idle. I want to know does these idle threads (45 total) will come in context switch and degrade the performance even when no task is submitted to them ?

If the pooled threads have no task, they are in state WAITING, meaning they have nothing to do besides wait for a signal for something to happen (in this case, waiting for a task to be submitted). They don't get scheduled any CPU time because they have nothing to do. The scheduler is smart enough to know this, so it's at this point where it's excluded from competing for resources with other, more active threads.
If a thread is in RUNNABLE state, then it might have something to actually do, and is given CPU time.
So excess threads in a pool don't compete with live threads, but they do take a small amount of native resources (not enough to really matter when talking about 60 threads).

I have 3 fixedThreadPools in my application with size of 20 each.
You mean, you are creating 3 ExecutorService instance of thread pool size 20. That means total 60 threads in pools ?
...15 threads from each pool sitting idle. I want to know does these
idle threads (45 total) will come in context switch..
I think, you are assuming to run all 60 threads at the same time, as you have mentioned 5 thread from each pool (i.e 15 threads) are executing. But remaining 45 threads (15 thread from each pool) are idle. But, that is not correct until they have tasks assign and number of available cores to execute them.
Please note, execution of thread depends on number of available cores (CPU). No matter, how many thread you create, if CPU is not available to execute each thread, they will be at Runnable state to get their turn.
JVM who decides which thread should run and how, mainly uses preemptive or time slicing scheduling to schedule the threads. In that time, if other thread get a new task (or has some task to execute), then they will at Runnable state to get their turn.

Unlike other executors, ForkJoinPool supports work stealing.
Yes, when there are no tasks for execution threads would be waiting, but before that, they try to steal works from pool's queues, and this will consume more CPU, then other executors (FixedThreadPool, CachedThreadPool). And waking up threads also needs time.
ForkJoinPool performs best when it has a lot job. If you don't have this, you better to use FixedThreadPool. Also, you should understand that typically ForkJoinPool, FixedThreadPool are for CPU intensive tasks. Otherwise, if you have IO intensive tasks is better to use CachedThreadPool. You could create one FixedThreadPool at all, but should aware that tasks could block each other.
Also, there is no reason create three ForkJoinPool pools with 60 threads unless you have at least 32 CPUs (but it hugely depends). As you can not utilize pools, that it is likely not your example. But keep in mind, if you run a lot of CPU intensive tasks in thread's count bigger then CPUs, then yes, you likely get worse performance, because of resource sharing, including context switches.

Related

Why does thread pool takes tasks independenty and not concurrently?

I am trying to get the basics very strong about thread pool. I learnt that it internally uses blocking queue to 'steal' tasks and run them into given threads in pool. Meaning that if I had 10 tasks and 5 threads, it could run only 5 tasks at the same time, until 1 finishes ENTIRELY.
Question is: Why not concurrently? Why not just time-slice those 10 tasks?
What is the reason of this implementation?
Why not concurrently? Why not just time-slice those 10 tasks?
You can have a thread pool that is able to perform ten concurrent tasks. You just need to configure it to have at least ten worker threads. "Time-slicing" tasks is what threads do. What thread pools do is:
Allow your program to control the number of threads that it uses to perform "background" tasks, and
Allow your program to re-use threads, which can be much more efficient than creating a new thread for each new task, and then destroying the thread when the task is complete.
In order to "time-slice 10 tasks", those tasks need to be in 10 separate threads that run concurrently.
The time-slicing scheduling algorithm is implemented by the operating system, not by Java. Time slicing applies to threads in Java because Java threads are implemented as native operating system threads: every Java thread has a native thread of its own, and these threads are scheduled by the operating system as it sees fit.
There is no difference between "thread pool threads" and "raw threads" here. If you give an instance of Runnable to a thread (whether it's part of a thread pool or not) it will run from beginning to end, subject to the time slicing scheduling algorithm of the operating system.
So why not use thousands of threads, why even bother with thread pools? It turns out that operating system threads are a relatively expensive and scarce resource, and therefore so are Java threads.
Since operating system threads are so expensive, Project Loom is investigating adding lightweight user space threads to Java. Some of the details in this answer may change when/if loom gets merged into main stream Java.
Some good answers but I thought I'd respond to your questions specifically.
I learnt that it internally uses blocking queue to 'steal' tasks and run them into given threads in pool. Meaning that if I had 10 tasks and 5 threads, it could run only 5 tasks at the same time, until 1 finishes ENTIRELY.
If you configure your thread pool to have 5 threads (Executors.newFixedThreadPool(5)) then it will start 5 threads to run your jobs. Initially 5 jobs are given to the 5 threads to run concurrently (if your server has 5 CPUs available). Once one of the 5 jobs finishes, a 6th job will be immediately started on the idle thread. This continues until all 10 jobs have been run.
Question is: Why not concurrently? Why not just time-slice those 10 tasks? What is the reason of this implementation?
You can instead use a cached thread pool (Executors.newCachedThreadPool()) if you want which will start a thread for each of the 10 jobs that you submit concurrently. This might work fine for 10 jobs but won't work well with 100,000 jobs – you would not want to start 100,000 threads. We use a fixed thread pool when we want to limit the number of jobs that run concurrently. Even though it seems like running 5 jobs concurrently would always run slower than running 10 jobs at once, but this isn't necessarily the case. There is a cost when the OS time slices between the jobs and the overall job throughput may be faster with 5 threads than 10 depending on how many processors your hardware has. Limiting the number of concurrent jobs also does not stress your server as much and should make your application work better with other running applications.
See my answer here about scaling threads: Concept behind putting wait(),notify() methods in Object class

Are new threads automatically assigned to a different CPU Core in Java?

In Java, and more specifically, Android,
are new Threads automatically assigned to a different CPU core than the one I am currently utilizing, or should I take care of that?
Also, does it matter how the new thread is created, using the Thread class or submitting a Runnable to an Executor, that maintans a pool of threads?
There is a similar question here, but the answer goes on to explain how the OP should address his particular problem, rather than diving into the more general case:
Threads automatically utilizing multiple CPU cores?
In Java, and more specifically, Android, are new Threads automatically assigned to a different CPU core than the one I am currently utilizing, or should I take care of that?
The decision of what threads run on what cores is handled by the OS itself (in Android, based off of the Linux scheduler). You cannot affect those decisions yourself; the decisions are automatic and dynamic.
does it matter how the new thread is created, using the Thread class or submitting a Runnable to an Executor, that maintans a pool of threads?
With respect to what cores a thread runs on, the OS neither knows nor cares whether an Executor is involved, or even if the programming language that app was written in has something called Executor.
In Java, and more specifically, Android, are new Threads automatically
assigned to a different CPU core than the one I am currently
utilizing, or should I take care of that?
In Java threads are simply separate sequence of executions, but in Android it is a little more complicated than that. Android creates one main thread per application. This main thread is responsible for the UI and other tasks related to events (queue). For doing background work you have to create separate worker threads.
Simple threads are handled by the Android OS automatically, and they may or may not run on separate cores. If you are running 10 threads, it is quite possible that they all run on one core leaving all other cores idle.
If you need to run more than one threads and you want to run each thread on a separate core you should use ThreadPoolExecutor; it will handle thread creation and map it on number of CPU cores available. You can set various parameters according to your requirement. See what Android is saying:
A ThreadPoolExecutor will automatically adjust the pool size (see
getPoolSize()) according to the bounds set by corePoolSize (see
getCorePoolSize()) and maximumPoolSize (see getMaximumPoolSize()).
When a new task is submitted in method execute(Runnable), and fewer
than corePoolSize threads are running, a new thread is created to
handle the request, even if other worker threads are idle. If there
are more than corePoolSize but less than maximumPoolSize threads
running, a new thread will be created only if the queue is full.
See ThreadPoolExecutor for detail.
does it matter how the new thread is created, using the Thread class
or submitting a Runnable to an Executor, that maintans a pool of
threads?
yes, see the answer above.
Update
By saying "to run each thread on a separate core use ThreadPoolExecutor", I meant that ThreadPoolExecutor can do that if it is used properly in a careful manner.
Java does not map threads directly on the CPU. Java leaves threads schedule (by mapping on to the OS' processes) on OS but how we create threads influence scheduling at OS level. However Java, can assign priority to threads but again it is up to the OS to honor these priorities.
There are various parameters we should consider while creating a thread pool, few are as follows:
i) Threads should be equal in complexity.
ii) Comparing CPU bound tasks with I/O bound, I/O bound task usually need more threads than available core for optimal utilization of CPU
iii) Dependency between threads effect negatively
If threads are created keeping these points in mind, ThreadPoolExecutor can help achieve a 100% of the CPU utilization, meaning one thread per core (if the thread pool's size is equal to the number of cores and no other thread is running). A benefit of ThreadPoolExecutor is that it is cost effective as compare to creating threads separately and it also eliminates context switching which wastes a lot of CPU cycles.
Achieving the 100% of the CPU utilization while making things concurrent, is not an easy task.
Whichever way Threads are created (Either using Thread class or using submitting the task to ThreadPoolExecutor) or task assigned to threads it will not make any impact on OS scheduling.
There is OS component Scheduler involved in this process which takes the responsibility to schedule the tasks or threads among the CPU cores(if cores are more than one) inside the OS.
This decision is taken by scheduler.
If there is only one core in system, Scheduler plays fair with threads by allowing them to do processing for some milliseconds one by one.

What happens to a thread as soon as it has completed its assigned task in java?

I have been working on a project in which my program creates around 500 threads during the execution. I find that my PC starts taking a huge load as soon as the program I execute the program. And it continues showing load after 75% of the threads have completed their job.
I want to know whether the threads whose work has finished were killed or not. And how does java deal with threads which have finished their job. Any help...
I find that my PC starts taking a huge load as soon as the program I execute the program. And it continues showing load after 75% of the threads have completed their job.
If 75% of the 500 threads have completed their job then that leaves 100+ threads that continue to run. 100 threads, if using a good amount of CPU, can more than swamp the processors on a box which I assume does not have 100s of cores. So your application may continue to show 100% CPU utilization until the number of running threads drops below the number of cores.
You should consider using a fixed sized thread pool instead of creating 500 concurrent threads. You then submit 500 tasks to the thread pool. This allows you to choose an appropriate number of threads to be running concurrently. The appropriate number of threads is highly dependent on the tasks being submitted. More CPU bound tasks should use fewer threads while IO bound tasks can use more. Doing some test runs with your application while adjusting the number of threads is the best way to optimize the value. I tend to start with 2 times the number of cores and then optimize from there.
// create a thread pool with 10 workers
ExecutorService threadPool = Executors.newFixedThreadPool(10);
// define your jobs somehow
for (MyRunnable job : jobsToDo) {
threadPool.submit(job);
}
// once we have submitted all jobs to the thread pool, it should be shutdown
threadPool.shutdown();
For more details, check out the ExecutorService tutorial.
I want to know whether the threads whose work has finished were killed or not. And how does java deal with threads which have finished their job. Any help...
The threads have most likely finished. After a thread leaves the run() method (either because it returns or throws an exception) it will no longer consume CPU and its underlying native thread can be reaped or reused. If there are no references to the Thread object, its memory will eventually be reaped by the garbage collector.
The JVM will garbage collect the Thread object, as long as there are no references to it, and as long as its run method returns. Thread is dead itself after its run method returns. It might still be in the heap, but it will not have its own stack anymore, and not do anything.
The only possible way that your threads have not been killed is that they still do something or you forgot to clean up references to your thread objects - but this is memory related.
If you allocated your threads through the thread pool, they are returned to the pool after the execution of the task. I this case, they might not be released after the completion of the task.
we should not create many threads to accomplish our task, it will give you many issues like OutofMemoryError. And also creation of thread is a costly task, so we should think of Thread pool i.e. ExecutorService in which we reuse the same threads again and again.
But any ways to answer you question after threads are created they die automatically i.e. it will be garbage collected, you don't need to do anything. Initially java provided methods like stop() or destroy() but these are deprecated for good reason.
You can read about a Thread's lifecycle. If the run method is over then they should not be consuming your cpu.
Threads who have finished their jobs will die. It won't consume any more CPU time.
You can use jstack to check how many threads are active running in your java process.

Java Multithreading - Starting a lot of threads and keeping them idle, vs lazy loading new threads?

I'm in a situation where I have 4 groups of 7 threads each. My CPU (core i7) is supposed to be able to handle 8 threads, so I'm considering going through each group one at a time, running the 7 threads, then moving to the 2nd group, running its 7 threads, then 3rd and 4th groups in the same way, and then starting back at 1st group, until user sends a stop command.
My question is, once each group of 7 threads has finished processing, should I keep those threads idle, or shut them down completely and restart a new group of 7 threads at the next iteration? Which method will be faster? This is for a very speed intensive app, so I need everything to happen as quickly as possible.
I will be using a FixedThreadPool to manage each group of 7 threads. So I could either just invokeAll() and then leave them alone (presumably to idle), or I could shutdown() each threadpool after the invokeAll() and start a new thread pool at the next iteration.
Which method will be faster?
My question is, once each group of 7 threads has finished one cycle of processing, should I keep those threads idle, or shut them down completely and restart a new group of 7 threads at the next cycle?
I would use a single ExecutorService thread-pool and reuse the same threads for all tasks. See the tutorial on the subject. A thread-pool is designed to execute any Runnable or Callable class so they are task agnostic. For example, you might have ParentResult and ChildResult classes. You can submit a Callable<ParentResult> to the thread-pool which will return a Future<ParentResult> and you can submit a Callable<ChildResult> to the same thread-pool which will return a Future<ChildResult>.
The only reason why you'd want to have "groups of threads" is if each thread has some state that it must maintain -- a database connection or something. Even then many people use thread-pools since it does much of the concurrency heavy lifting for you.
If you do have to keep this state then I would certainly not shutdown the pools and then restart them later. A dormant thread/pool is taking no system resources aside from memory. The only reason why you would ever do this is if you are forking 100s of thread for the task but at that point, you should consider re-architecting your application.
You need not to schedule your threads manually. Start all 28 threads at once - this would not be slower, but well can be faster.
When you say your processor has 8 threads, I think you mean it has has 4 cores with hyperthreading. Java does not use threads in the same sense as your processor, so those 7 threads are of a different type to your processors.
The JVM handles processor usage, and is (IIRC) limited to using 1 core. The threads java uses are specific to the JVM, and are wholly separate.
As for your actual question, try testing different thread combinations to see which is fastest, which will give you a more accurate answer than arm-chair theorising.
I too prefer Alexei Kaigorodov suggestion to start all 28 threads. But I suggest you to replace newFixedThreadPoolwith new Executors API: ( since Java 8)
static ExecutorService newWorkStealingPool()
Creates a work-stealing thread pool using all available processors as its target parallelism level.
Above API returns ForkJoinPool type of ExecutorService
Now you don't need to worry utilization of idle threads. Java will take care better utilization of idle threads with work-stealing mechanism.
If you still need four different groups of FixedThreadPools, you can proceed with invokeAll. Don't shutdown ExecutorService to switch between multiple pools. You one ExecutorService effectively. If you want to poll the result of Future tasks using invokeAll, use CompletableFuture and poll it to know the status of task execution.
static CompletableFuture<Void> runAsync(Runnable runnable, Executor executor)
Returns a new CompletableFuture that is asynchronously completed by a task running in the given executor after it runs the given action.

Is ScheduledThreadPoolExecutor ok for doing multiple tasks at same time?

The docs for ScheduledThreadPoolExecutor says that -
Tasks scheduled for exactly the same execution time are enabled in first-in-first-out (FIFO) order of submission.
Does this mean that the tasks which SHOULD be done at the same time are never done at the same time. Instead they are executed in FIFO order ?
If that is true then which class do I use which is better than Timer and also does not have this FIFO problem ?
The way a ScheduledThreadPoolExecutor works is there is a single "scheduling" or master thread which checks for tasks to execute.
If it finds a task, it delegates it to a "worker" thread from the pool.
If multiple tasks are ready to be executed, they are "kicked off" one at a time, though once "kicked off", subsequent processing is concurrent, per Java's definition.
If you have two tasks that are both scheduled through the executor for the same time, the order in which they complete could vary from run to run and unless you put in specific controls such as locks, waits, etc... to handle this, it's up to java's thread scheduling (how java allots time to threads on a core) to determine how and when what gets processed. Please note that setting up such locks, waits, etc... is a deceptively complex task prone to race conditions leading to unexpected deadlocks, live locks, etc...
It depends on the size of your thread pool. If you schedule 1000 tasks to fire at midnight, and you only have 25 threads, then only 25 can be executed initially, while the rest must wait for available threads. FIFO here refers to the order in which the executor will hand tasks off to the execution threads.
Please note that the docs talk about "enabling" the tasks and that we are talking about a threadpool executor. :-)
That means the tasks will wait until the designated time, then they are treated as if put into a normal ThreadPoolExecutor. If there are enough threads available in the pool all these tasks will be run in parallel.
Only if you have more tasks becoming active than available threads in the pool some tasks will have to wait.

Categories