Jconsole live threads count and java ExecutorService - java

Monitoring our app using JConsole over a period of time shows that the “live thread” count is increasing constantly. Increasing thread count sounds like a bad thing to me, or am I wrong?
Synopsis:
In our app we create thread pools for various collectors using Executors.newFixedThreadPool, Executors.newSingleThreadScheduledExecutor. These collectors are called every few minutes.
And there is this other service which is called n times by the above collectors during every collection. This service generates a single thread (Executors.newFixedThreadPool(1);) that executes a FutureTask. For all the above ExecutorServices we call shutdownNow() only if an exception is caught and leave the rest for GC.
1) Do I need to shutdown the executors once the process is finished or can I rely on GC?
Thanks for your suggestions and insights
Ajju

One should call shutdown explicitly on executor service - executor.shutdown() for orderly shutdown & reclamation of resources (old tasks are executed while new ones are not accepted).
shutdownNow() attempts to stop all actively executing tasks, halts the processing of waiting tasks, and returns a list of the tasks that were awaiting execution (there is no guarantee about the executing tasks - they may or may not execute - this is a best attempt).

The point of a thread pool is to avoid the overhead of spawning new threads during processing. You are NOT supposed to spawn new thread pools ! (Which is what you're doing here Executors.newFixedThreadPool(1);)
You should set up your thread pools when your application starts, and inject them into your processing objects.

Related

Difference between ForkJoinPool and normal ExecutionService?

I read a great article about the fork-join framework in Java 7, and the idea is that, with ForkJoinPool and ForkJoinTask, the threads in the pool can get the sub tasks from other tasks, so it's able to use less threads to handle more tasks.
Then I tried to use a normal ExecutorService to do the same work, and found I can't tell the difference, since when I submit a new task to the pool, the task will be run on another available thread.
The only difference I can tell is if I use ForkJoinPool, I don't need to pass the pool to the tasks, because I can call task.fork() to make it running on another thread. But with normal ExecutorService, I have to pass the pool to the task, or make it a static, so inside the task, I can call pool.submit(newTask)
Do I miss something?
(You can view the living code from https://github.com/freewind/fork-join-test/tree/master/src)
Although ForkJoinPool implements ExecutorService, it is conceptionally different from 'normal' executors.
You can easily see the difference if your tasks spawn more tasks and wait for them to complete, e.g. by calling
executor.invoke(new Task()); // blocks this thread until new task completes
In a normal executor service, waiting for other tasks to complete will block the current thread. There are two possible outcomes: If your executor service has a fixed number of threads, it might deadlock if the last running thread waits for another task to complete. If your executor dynamically creates new threads on demand, the number of threads might explode and you end up having thousands of threads which might cause starvation.
In opposite, the fork/join framework reuses the thread in the meantime to execute other tasks, so it won't deadlock although the number of threads is fixed:
new MyForkJoinTask().invoke();
So if you have a problem that you can solve recursively, think of using a ForkJoinPool as you can easily implement one level of recursion as ForkJoinTask.
Just check the number of running threads in your examples.

New threads vs. reusing threads

We have a desktop application that has some background threads and, because of execution of external commands, also needs threads for handling the out and err streams.
We could either create new threads and let them finish or we could reuse threads. Would reusing threads have some benefit, e.g. in case of performance or memory usage?
There is no way to reuse a Thread because Thread once finishes (exit the run() method) its Thread.State passes from Thread.State.RUNNABLE to Thread.State.TERMINATED and the Thread class does not have a setState(Thread.State) method for setting its state to reuse it.
However we can take help of Thread Pooling in Java. In case of thread pool, a group of fixed size threads are created. A thread from the thread pool is pulled out and assigned a job by the service provider. After completion of the job, thread is contained in the thread pool again.
Advantage of Thread Pooling :
Thread pooling saves the virtual machine the work of creating brand new threads for every short-lived task.
It minimizes overhead associated with getting a thread started and cleaning it up after it dies
By creating a pool of threads, a single thread from the pool can be recycled over and over for different tasks.
Reduce response time because a thread is already constructed and started and is simply waiting for its next task
JDK 1.5 and above, you should try not to create Thread as much as possible.
Refer : http://docs.oracle.com/javase/tutorial/essential/concurrency/pools.html. Try to use Thread pool executor.
Reusing a thread has the following advantage:
no new object needs to be created (thread object)
lower latency because the task can be picked up by an existing idle thread
no old object needs to be garbage collected
using a pool also introduces a limit to concurrently running threads (averages out load spikes)

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.

increase Thread start performance in java

Is there a way to increase the performance of Thread.start method. as i know Thread.start will call the run method of the tread in a separate thread but i have found that it need time more than simple method call in the calling context.
Starting threads definitely involves overhead. You may want to consider thread pooling.
http://docs.oracle.com/javase/tutorial/essential/concurrency/pools.html
Thread.start is native. It does a lot more than calling run - it uses Operating System calls to create a thread stack and lots of other things. Consider using a Thread Pool.
Starting threads, context switching and destroying threads all require precious CPU cycles. So it is best to use Thread Pooling which suits your requirement.
There are various options available:
Cached Thread Pool - caches some threads to improve performance
Single Thread pool executor - A single thread executor
Fixed Thread Pool executor - An executor with fixed size
Switching can be reduced by creating n threads based on your hardware configuration and other parameters.
Advantage of executors over Thread.start():
Re use of existing threads, so threads are not created every time a task is submitted
Thread management is done by executors
Thread creation always takes time. The traditional approach
new Thread(runnableObj).start();
creates new Thread everytime we call start() method.
Use Executors, if you don't want to spend extra time in creating threads while your business logic is being run. You can configure and create Thread Pools when your application starts.
Here is a good short tutorial for Executors

How to 'kill' the threads from an executor?

I have an tomcat webapp where I use a java executor to execute some runnables.
First I allocate the executor service from my executor instance like this:
executorService = Executors.newFixedThreadPool(nThreads, new MyThreadFactory(threadFactoryName))
Then, I launch task using the executor service:
executorService.execute(new MyRunnable);
Then, it seems to work. But my problem is, I am chasing some sort of leak where I get this error after a while of running the server:
Caused by: java.lang.OutOfMemoryError: unable to create new native thread
at java.lang.Thread.start0(Native Method)
at java.lang.Thread.start(Thread.java:640)
at java.util.concurrent.ThreadPoolExecutor.addIfUnderCorePoolSize(ThreadPoolExecutor.java:703)
at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:652)
at something.server.ThreadExecutor.execute(MyRunnable.java:91)
I used the java VisualVM on tomcat instance to trace the thread allocation. I see that when I call 'newFixedThreadPool' I see 'nThreads' new threads. But after their job is done, I see the state of the threads to be on 'wait'.
Is that normal? I don't believe it is, I know the runnables finish their job but the executor service never frees the threads. What can I do to free them, or am I completely out of scope?
I think you are instantiating a new ExecutorService for every request, or something like that.
You should either instantiate only one ExecutorService, and reuse it, or call shutdown() on the service after you have finished submitting tasks. The shutdown function will wait for the tasks to finish, and then free the threads.
You are instantiating a fixed thread pool. The ExecutorService is not going to release the threads until you terminate the ExecutorService itself by calling ExecutorService.shutdown() or ExecutorService.shutdownNow().
Is that normal? I don't believe it is, I know the runnables finish their job but the executor service never frees the threads.
Yes it is normal. Indeed, this behaviour is desirable because creating a new thread is an expensive operation. The pool threads (or at least the 'core' pool threads) will continue to exist until the executor gets shut down.
What can I do to free them, or am I completely out of scope?
You should be able to configure your thread pool to have a smaller 'core' thread pool, and/or a smaller keepAlive time. Refer to the javadoc for details.
[M]y problem is, I am chasing some sort of leak where I get this error after a while of running the server:
That OOME is not necessarily an indication of a leak. It could be a sign that you haven't left enough non-heap memory for the number of threads that you are trying to create. (Or to put it another way, that your thread pool is too big.)

Categories