Thread pool issue in java - java

HI the following code is used in a application
threadPool.shutdown();
while (!threadPool.awaitTermination(10, TimeUnit.SECONDS)) {
logger.info("Waiting for "
+ (threadPool.getQueue().size() + threadPool
.getActiveCount()) + " jobs to complete.");
}
when application is running it strucked in the loop
Waiting for 134 jobs to complete.
Waiting for 134 jobs to complete.
Waiting for 134 jobs to complete.
the above statement is coming continuosly,actually thread is performing update operation on database.will increasing the time to more than 10sec will help in this situation.any suggestion is helpful

The documentation for ThreadPoolExecutor.shutdown() says:
Initiates an orderly shutdown in which previously submitted tasks are
executed, but no new tasks will be accepted. Invocation has no
additional effect if already shut down.
Which means that your worker threads are responsible for shutting themselves down. You haven't provided the code for your workers, but I'm assuming they are performing a blocking operation that doesn't exit. A common approach to solving this is to have the workers routinely check in on a shared variable of some kind that is set just before the shutdown call. They are effectively told to stop whatever they're working on. An AtomicBoolean should do the trick.

Related

will java ExecutorService shutDown method can ensure all submit task will finally submitted

As the ExecutorService document explains The shutdown() method will allow previously submitted tasks to execute before terminating. So in my initial understand, all submitted task will still be finally completed when we kill thread through ctrl+c. But it seemed the actually result is not.
The generation of the executorService as below:
CORE_POOL_SIZE = 1
return new ThreadPoolExecutor(CORE_POOL_SIZE, numConsumers,
KEEP_ALIVE_TIME, TimeUnit.SECONDS,
new LinkedBlockingQueue<>(),
consumerThreadFactory);
And in my task, I will log some information the task code sample like this:
log.info("before come into sleep.....")
try {
Thread.sleep(sleepTime);
} catch (InterruptedException e) {
log.warn(" exception during sleep.....{}", request.getExecutionId());
e.printStackTrace();
}
log.info("after come into sleep...")
I submit several task and then terminal thread through control+c, and the result is that only the log before come into sleep is print.
So I dont know whether my understand is correct that shutDown can ensure all submitted task be completed finally. I also google some similar question but find there are no explicit answer.
Control+c kills entire JVM
Pressing Control+c on the console terminates the entire Java process running your threads. See Wikipedia.
You are interrupting the JVM. This is not a graceful way to interact with your Java app.
So, no, you should not expect your executor service to continue running submitted tasks. You killed it.
The JVM is generally not designed to be manipulated in the console after launch. After launch, the only two ways I know of for interacting with the JVM is:
The user-interface of your app, GUI or console-based.
Java Management Extensions (JMX)
You said:
we kill thread through ctrl+c
No, ctrl+c does not specifically kill a thread. It kills your entire JVM.
awaitTermination
After calling ExecutorService#shutdown, if you want your code to block and wait until all submitted tasks are done, call ExecutorService#awaitTermination. Specify a certain amount of time to wait before throwing an exception if tasks are still running.
This waiting for termination is shown in the JavaDoc and has been discussed in many other Questions and Answers on Stack Overflow, some authored by me. So search to learn more.
I believe it is clear from the docs for ExecutorService (https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html#shutdown--) that it doesn't wait for the tasks to complete. We have awaitTermination for this purpose.
This method does not wait for previously submitted tasks to complete execution. Use awaitTermination to do that.
A clear example of how to achieve this is available in Usage Example section of this documentation as well.
Why is awaitTermination important during graceful shutdown?
Using shutdown() is like informing your intention to stop all the threads managed by the ExecutorService. There is no blocking involved here. Your main thread shall resume execution and continue executing subsequent code after shutdown(). While handling graceful shutdown of a JVM (https://docs.oracle.com/javase/8/docs/technotes/guides/lang/hook-design.html), a separate thread will be called expecting it to complete its task and when it does complete, JVM shuts down. If you need to wait for the tasks to complete, block the shutdown hook thread using awaitTermination().

ThreadPoolExecutor does not terminate but shutdownNow() returns an empty list

in some of my jUnit tests I create a ThreadPoolExecutor to test if my code does not have obvious concurrency errors. At the end of each such test I shutdown the executor and verify if all tasks were completed, similarly to the below code:
// wait on a conditional that indicates that results are available
executor.shutdown();
executor.awaitTermination(100l);
// do other result verifications here
if ( ! executor.isTerminated()) {
final var stuckTasks = executor.shutdownNow();
for (var stuckTask: stuckTasks) log.severe("stuck " + stuckTask);
fail("executor not terminated, " + stuckTasks.size() + " tasks remaining");
}
If I run these tests in a loop, every few hours I get a failure with message "executor not terminated, 0 tasks remaining"
Is it normal and can be safely ignored or does it mean that my code has some concurrency errors in fact?
Apart from unfinished tasks, are there any other possible reasons for executor to not terminate?
I'd like to emphasize that it has NEVER happened for the number of remaining tasks to be nonzero (even after running the tests in a loop for more than 12 hours, where a single run takes about 2s) and all other verifications pass correctly, which would be impossible if any of the tasks submitted to this executor actually got stuck.
100ms that I await for termination is a lot in this case as all the submitted tasks take less than 10ms and they are all supposed to be finished even before awaitTermination(100l) is called as results were already available.
I'm using openJdk-11 on ubuntu in case it matters.
The code in question is here if anyone is interested (I have since modified it to fail only if the number of remaining tasks is nonzero, as so far it seems harmless). Failure was happening only on userExecutor (never on grpcExecutor, which makes it more strange) in various random test methods in this class.
Thanks!
update:
As #Thomas pointed in the comment, shutdownNow() returns only tasks that were not even started. In addition to this, getActiveCount() should be checked also.
To summarize the comments:
ThreadPoolExecutor maintains a queue of not yet and shutdownNow() drains that queue and returns its contents. That means you'll only get the tasks that have not started yet.
This is consistent with the Javadoc which states:
Returns: list of tasks that never commenced execution.
Additionally, there is a set of workers in ThreadPoolExecutor (the actual thread pool) which can be queried for the number of active tasks using ThreadPoolExecutor.getActiveCount(). That method basically queries each workder to see if it currently has a lock which indicates it is executing a task.
For a more complete picture, have a look at ThreadPoolExecutor.getTaskCount(). It adds up a couple of different numbers:
number of completed tasks reported back to the executor (by workers that got removed)
number of completed tasks for each existing worker
+1 for each currently active workder
the size of the work queue (which is returned by shutdownNow().
It would be great if we'd get access to what the workers are currently executing but I didn't find a way since workers (the set of workers) isn't exposed to the outside world and is private and workers don't even seem to hold a reference to the tasks they're executing (at least not directly).
Now shutdown() tries to interrupt idle workers, not active ones so awaitTermination() might time out due to workers still being active. On the other hand shutdownNow() interrupts all workers.

Java thread pool: What happens to idle threads

I am trying to understand multi-threading in Java. I have written the following java program to test thread pool.
public class ThreadPoolTest
{
public static void main(String[] args)
{
ExecutorService executorService = Executors.newFixedThreadPool(5);
for( int i = 0; i < 3; i++ )
{
executorService.submit(new Task(i+1));
}
executorService.shutdown();
}
public static class Task implements Runnable
{
private int taskId;
public Task(int id)
{
taskId = id;
}
#Override
public void run() {
System.out.println("Executing task " + taskId + " performed by " + Thread.currentThread().getName() );
try
{
Thread.sleep(3000);
}
catch(InterruptedException interruptEx)
{
System.out.println(Thread.currentThread().getName() + " got interrupted ");
}
System.out.println("Finished executing task " + taskId );
}
}
}
The main thread creates executor which creates 5 threads and I have submitted only 3 tasks. After that I am shutting down the executor. When I run the code, the main thread finishes before the child threads. In this case, does JVM takes care of the child threads?
Also I have created a thread pool with 5 threads, but submitted only 3 tasks. Will the remaining 2 threads are terminated when the main thread exits?
What actually happens when the executor service is shutdown?
From the doc of ExecutorService#shutdown():
Initiates an orderly shutdown in which previously submitted tasks are
executed, but no new tasks will be accepted.
This means that all the Jobs you submitted to the Executor will finish on their own time without interrupting or "hurrying" them, and the executor will finish up the worker threads properly, but neither will the service accept new Jobs, nor will it terminate instantly.
Compare ExecutorService#shutdownNow(), which will try to terminate as quickly as possible.
The Worker threads that the executor creates are inner classes that have a reference back to the executor itself. (They need it to be able to see the queue, runstate, etc!) Running threads are not garbage collected, so with each Thread in the pool having that reference, they will keep the executor alive until all threads are dead. If you don't manually do something to stop the threads, they will keep running forever and your JVM will never shut down.
In case of 5 threads where 3 tasks are only spawned, 2 unused thread will never be started but there references will remain as it is until shutdown is called in finalize() or all the live threads completes there execution.
Following is the comment from JAVA Docs:
A pool that is no longer referenced in a program AND has no remaining threads will be >shutdown automatically. If you would like to ensure that unreferenced pools are reclaimed >even if users forget to call shutdown(), then you must arrange that unused threads >eventually die, by setting appropriate keep-alive times, using a lower bound of zero core >threads and/or setting allowCoreThreadTimeOut(boolean).
In this case, does JVM takes care of the child threads?
The OS manages threads and determines when they are run.
Also I have created a thread pool with 5 threads, but submitted only 3 tasks. Will the remaining 2 threads are terminated when the main thread exits?
No, the threads run until you shut them down.
What actually happens when the executor service is shutdown?
The threads are interrupted and no new tasks will start. However, if you have a task which ignores interrupts it could keep running indefinitely.
When the last non-deamon thread stops the shutdown hook (if any) are triggered.
does JVM takes care of the child threads
JVM only complete its execution after completing all daemon threads. If you are creating your as non daemon then it will wait till all non daemon threads complete.
Will the remaining 2 threads are terminated when the main thread exits
Threads will be created in ondemand mode. So here 3 threads only created not 5.
What actually happens when the executor service is shutdown
Initiates an orderly shutdown in which previously submitted tasks are executed, but no new tasks will be accepted. Invocation has no additional effect if already shut down.
This method does not wait for previously submitted tasks to complete execution. Use awaitTermination to do that.

How is an executor terminated in my Java program?

This question is related to my previous question : Why the speed of a Java process inside multiple loops slows down as it goes?
In order to find the problem of that question, I looked closely at my code and found some executors in my app are not terminated, since I'm in the process of learning how to use executors, I copied some online sample codes and used them in my app, and I'm not sure if I'm using them correctly.
What's the difference between the following 2 approaches of using executors ?
[1]
Executor executor=Executors.newFixedThreadPool(30);
CountDownLatch doneSignal=new CountDownLatch(280);
for (int N=0;N<280;N++)
{
...
executor.execute(new SampleCountRunner(doneSignal,...));
}
try { doneSignal.await(); }
catch (Exception e) { e.printStackTrace(); }
[2]
ExecutorService executor=Executors.newFixedThreadPool(30);
for (int i=0;i<60;i++)
{
...
executor.execute(new xyzRunner(...));
}
executor.shutdown();
while (!executor.isTerminated()) { }
It seems to me after the 1st one is done, the executor still has an active pool of threads running and waiting for more tasks, they DO consume cpu time and memory.
The 2nd one will terminate all active threads in the pool after the shutdown() method is run, and all previously active threads won't take any more cpu time or memory after that point.
So my questions are :
[1] Am I correct ?
[2] How to terminate the pool of threads in the 1st case ? There is no "executor.shutdown()" for Executor
Edit :
Problem solved, I changed Executor in [1] to ExecutorService, and added :
executor.shutdown();
while (!executor.isTerminated()) { }
Now when my program ends, it won't have a lot of threads active any more.
It seems to me after the 1st one is done, the executor still has an active pool of threads running and waiting for more tasks, they DO consume cpu time and memory.
Not exactly. In first approach , after the tasks are all done ( as signalled by the latch ) , the executor is definitely NOT shutdown - but the threads in the executor do NOT consume cpu ( they consume minimum memory needed for thier structures yes ).
In this approach - you are explicitly in control of knowing when and how your tasks are completed. You can know if the tasks have succeeded or failed , and can decide to resubmit the tasks if needed.
The 2nd one will terminate all active threads in the pool after the shutdown() method is run, and all previously active threads won't take any more cpu time or memory after that point.
Again ,not exactly .In this approach , the ExecutorService does not shutdown immediately after the call to shutdown(). It waits for the already submitted tasks to complete , but here you do not directly know if these tasks completed successfully or they failed ( by throwing some Exception ).
And until the already submitted tasks are completed - your isShutDown() will do a tight loop ( it will spike the cpu to near 100% ) .
Thread pools (ExecutorService) should generally speaking not be created/destroyed regularly. Rather they should be long lived (perhaps entire life of application) to avoid the (significant) overhead of thread creation/destruction.
If you want to submit a list of tasks and wait for all to complete, use ExecutorService.invokeAll() rather than trying to track completion by a countdown latch.
The ExecutorService interface provides 2 mechanisms to shutdown: shutdown and shutdownNow. The first simply stops taking new jobs and will stop threads as currently executing and already submitted work is done. The second will attempt to interrupt all work in progress and will not even work on already submitted but not yet started jobs.

Executors threads not terminating

I am using Executors.newFixedThreadPool(100) method.
Single command execution needs approx 20 threads. After executing the command 5-6 times, application stops responding.
My thread is implementing Callable.
I doubt, that thread doesn't terminate after completion.
I have also called shutdown() to terminate the thread.
Can anybody please tell, when I use get() method to retrieve the thread's result, does it gets terminated(means, its removed from the queue) or it is still there in the queue, which is used by pool to store the threads.
The threads don't terminate. What happens is this:
All worker threads wait for the input queue
One thread pops the head element from the queue
It runs the Callable
It pushes the result into the result queue
It waits for a new element in the input queue
So either the result queue overflows or your Callable doesn't return.
get() is a blocking call - that means the calling thread halts until the running thread has completed its task and the result is available.
The Executor takes care of taking tasks from the queue and cleaning up, so the answer is "no" - it isn't "still on the queue"
Caution using 100 threads - that's a ridiculously high number. Try between 2 and 8 for a typical machine (all depends on how much time is spent waiting for other things eg I/O - the more CPU bound your tasks are, the less threads you should use.
Even after calling get(), the thread would still be in the queue. Infact the API ensures that even if a thread dies, it recreates one to maintain "fixedness"(fixed no of threads in your pool)
Note that if the threads in your pool are actually doing some task(apart from waiting), calling shutdown will not terminate the thread. So, for e.g. if your threads are in a infinite loop doing something, then calling shutdown is useless.
Calling shutdown() only stops the thread pool from accepting new tasks and allows all thread to finish once all tasks have been performed.
How many cores do you have? If you have 100 busy threads, and say 4 cores every thread is only going to get a small amount of CPU time.

Categories