My web application (on Tomcat) provides “on the fly” logic execution functionality.
The problem is the “on the fly” logic can contains infinite loop , or something long duration.
My solution is timeout: to run the “on the fly” logic in a new daemon thread and go back main thread in timeout, p-code as below:
ExecutorService executor = Executors.newSingleThreadExecutor(new ThreadFactory(){
#Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r);
result.setDaemon(true);
return t;
}});
Future<Object> future = executor.submit(callable/* 'on the fly' callable: it can be infinite loop, the callable is out of my control */);
//Back to main thread
return future.get(timeout, TimeUnit.MILLISECONDS);
However, the daemon thread is still running, although future.get() returns in timeout. The daemon is terminated until Tomcat stops.
Now my latest solution is create a new Java process Runtime.getRuntime().exec("java MyProgram"). MyProgram contains future.get() shown before. The daemon is terminated once main thread quits as expected.
I am here to ask more elegant solution to terminate thread in web application. The new Java process is heavy and out control of web application.
Thanks!
threading in a managed environment is generally a bad idea. why not use some sort of abstraction like JMS to start a background handler every time someone sends a request ? that way you can control the number of active threads (jms pool size)
Related
Is there a way to find hanging or stuck threads in executor service thread pool?
or
Is there a way to find if all threads in executor service is hanging or stuck, so we could shutdown or restart executor service?
Stuck or hanging means, All Threads in executor service might be with Waiting state for long time without doing anything. So no more threads to process other waiting tasks in executor service in such scenarios
If you know how long the task will be running you can use Future#get to timeout the task so that it will not get stuck.
One example is supposed we want to run X number of task
/*
spawn one thread only wait for each task to finish
*/
ExecutorService executorService=Executors.newSingleThreadExecutor();
List<Runnable> runnables = ... ;
for(Runnable task : runnables)
{
Future<?> future=executor.submit(task);
try
{
future.get(2,TimeUnit.SECONDS); // exit task in 2 seconds
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
I am trying to apply the priciple of Multithread producer/consumer of some datas using two threadPoolExecutors, i noticed that everything works fine but the program refuse to shut down and some threads are still running after shutting down the 2 threadPools:
In main class:
ExecutorService executor = new ThreadPoolExecutor(10, 10, 40, TimeUnit.SECONDS,
new ArrayBlockingQueue<Runnable>(edmsIds.size()));
ExecutorService consumerExecutor = new ThreadPoolExecutor(10, 10, 0L, TimeUnit.SECONDS,new ArrayBlockingQueue<Runnable>(edmsIds.size()));for(
String edmsID:edmsIds)
{
Runnable worker = new BatchWorkerThread(resumeFile, stratrKeysToUpdate, xslFiles, errorThrown, edmsID,
consumerExecutor, edmsIds.size(), executor);
executor.execute(worker);
}
In producer Class:
while (edmsNumber > 0) {
Runnable consumer = new ConsumerThread(brokerWorker);
consumExecutor.execute(consumer);//decreasing the edmsNumber
}
if (edmsNumber < 1) {
prodExecutor.shutdownNow();
consumExecutor.shutdownNow();
}
See the doc:
There are no guarantees beyond best-effort attempts to stop processing
actively executing tasks. For example, typical implementations will
cancel via Thread.interrupt(), so any task that fails to respond to
interrupts may never terminate.
If the running task is not interruptable(does not respond to interrupt singal), it will continue execute.
Actually i wanted to post the cause of the problem and the solution :
Cause
i was trying to shutdown the excutor while it is not terminated yet.
Solution
shut it down only after its termination using a simple code.
For example :
prodExecutor.shutdownNow();
while (!prodExecutor.isTerminated()) {}
Another solution is to use ExecutorCompletionService if you want to take tasks as they complete you need an ExecutorCompletionService. This acts as a BlockingQueue that will allow you to poll for tasks as and when they finish.
I'm running a service of generating a big file (It is a report in BIRT) in Java back code and it takes a lot of time my question is what is the best way to manage it with
daemon = true or
daemon = false
and the priority
new Thread(new Runnable() {
public void run(){
try {
task.run();
engine.destroy( );
}
catch ( EngineException e1 ) {
System.err.println( "Report " + reportFilepath + " run failed.\n" );
System.err.println( e1.toString( ) );
}
}
}).start();
Creating new Thread()s in Java EE is considered bad practice. Instead, you should use a service such as ManagedExecutorService (MES) and submit runnables to it.
The benefit of using a MES over running your own threads is that the resources used by a MES can be controlled by the Java EE app server.
Now to answer your question about daemon threads and priorities.
daemons: Submitting tasks to an MES is always non-blocking, and the result of a task can optionally be checked, so this essentially makes these tasks daemon threads.
priority: there isn't a Java EE standard way that I know of to control thread priority. You will have to check with your application server implementation to see if there are properties you can pass in during task submit to indicate a thread priority.
There is only one difference between a daemon thread and a normal thread: The existence of a normal, running thread will prevent the JVM from shutting itself down, but the existence of a running daemon thread will not. There is no impact on performance
This seemed to happen in my application but was almost certainly the result of something else going on in my Maven / JUnit test case environment (on code I haven't even fully read - maintaining a foreign project). The following code works as desired, and the TPE doesn't require shutdown:
final ScheduledThreadPoolExecutor pool = new ScheduledThreadPoolExecutor(1, new ThreadFactory() {
#Override
public Thread newThread(Runnable task) {
Thread thread = new Thread(task, replenisherThreadName);
thread.setDaemon(true);
return thread;
}
});
if it is truly a daemon thread, then it is not keeping your application alive. your problem lies elsewhere (or it's not really a daemon thread).
Not sure about these daemon threads getting created via your program but ideally we should try to shutdown executor service, after completing our work. The reason being, I have observed it in many applications that when these services are not shutdown properly; thread count keep on piling up and this makes application unstable.
The following piece of code tries to accompolish this.
The code loops forever and checks if there are any pending requests to be processed. If there is any, it creates a new thread to process the request and submits it to the executor. Once all the threads are done,it sleeps for 60 seconds and again checks for pending requests.
public static void main(String a[]){
//variables init code omitted
ExecutorService service = Executors.newFixedThreadPool(15);
ExecutorCompletionService<Long> comp = new ExecutorCompletionService<Long>(service);
while(true){
List<AppRequest> pending = service.findPendingRequests();
int noPending = pending.size();
if (noPending > 0) {
for (AppRequest req : pending) {
Callable<Long> worker = new RequestThread(something, req);
comp.submit(worker);
}
}
for (int i = 0; i < noPending; i++) {
try {
Future<Long> f = comp.take();
long name;
try {
name = f.get();
LOGGER.debug(name + " got completed");
} catch (ExecutionException e) {
LOGGER.error(e.toString());
}
} catch (InterruptedException e) {
LOGGER.error(e.toString());
}
}
TimeUnit.SECONDS.sleep(60);
}
}
My question is most of the processing done by these threads deal with database. And this program will run on a windows machine. What happens to these threads when someone tries to shutdown or logoff the machine.? How to gracefully shutdown the running threads and also the executor.?
A typical orderly shutdown of an ExecutorService might look something like this:
final ExecutorService executor;
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
executor.shutdown();
if (!executor.awaitTermination(SHUTDOWN_TIME)) { //optional *
Logger.log("Executor did not terminate in the specified time."); //optional *
List<Runnable> droppedTasks = executor.shutdownNow(); //optional **
Logger.log("Executor was abruptly shut down. " + droppedTasks.size() + " tasks will not be executed."); //optional **
}
}
});
*You can log that the executor still had tasks to process after waiting the time you were willing to wait.
**You can attempt to force the executor's worker Threads to abandon their current tasks and ensure they don't start any of the remaining ones.
Note that the solution above will work when a user issues an interrupt to your java process or when your ExecutorService only contains daemon threads. If, instead, the ExecutorService contains non-daemon threads that haven't completed, the JVM won't try to shutdown, and therefore the shutdown hooks won't be invoked.
If attempting to shutdown a process as part of a discrete application lifecycle (not a service) then shutdown code should not be placed inside a shutdown hook but at the appropriate location where the program is designed to terminate.
The book "Java Concurrency in Practice" states:
7.4. JVM Shutdown
The JVM can shut down in either an
orderly or abrupt manner. An orderly
shutdown is initiated when the last
"normal" (nondaemon) thread
terminates, someone calls System.exit,
or by other platform-specific means
(such as sending a SIGINT or hitting
Ctrl-C). [...]
7.4.1. Shutdown Hooks
In an orderly shutdown, the JVM first
starts all registered shutdown hooks.
Shutdown hooks are unstarted threads
that are registered with
Runtime.addShutdownHook. The JVM makes
no guarantees on the order in which
shutdown hooks are started. If any
application threads (daemon or
nondaemon) are still running at
shutdown time, they continue to run
concurrently with the shutdown
process. When all shutdown hooks have
completed, the JVM may choose to run
finalizers if runFinalizersOnExit is
true, and then halts. The JVM makes no
attempt to stop or interrupt any
application threads that are still
running at shutdown time; they are
abruptly terminated when the JVM
eventually halts. If the shutdown
hooks or finalizers don't complete,
then the orderly shutdown process
"hangs" and the JVM must be shut down
abruptly. [...]
The important bits are,
"The JVM makes no attempt to stop or interrupt any application threads that are still running at shutdown time; they are abruptly terminated when the JVM eventually halts." so I suppose the connection to the DB will abruptly terminate, if no shutdown hooks are there to do a graceful clean up (if you are using frameworks, they usually do provide such shutdown hooks). In my experience, session to the DB can remain until it is timed out by the DB, etc. when the app. is terminated without such hooks.
Since adding a shutdown hook to explicitly call shutdown() didn't work for me, I found an easy solution in Google's Guava:
com.google.common.util.concurrent.MoreExecutors.getExitingExecutorService.
You can either call shutdown() on the ExecutorService:
Initiates an orderly shutdown in which
previously submitted tasks are
executed, but no new tasks will be
accepted.
or you can call 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 are no guarantees beyond
best-effort attempts to stop
processing actively executing tasks.
For example, typical implementations
will cancel via Thread.interrupt(), so
any task that fails to respond to
interrupts may never terminate.
Which one you call depends how badly you want it to stop....
I had similar issue, i use to get error like
o.a.c.loader.WebappClassLoaderBase :: The web application [ROOT] appears to have started a thread named [pool-2-thread-1] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
sun.misc.Unsafe.park(Native Method)
java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
Bellow code fixed it
private ThreadPoolExecutor executorPool;
#PostConstruct
public void init() {
log.debug("Initializing ThreadPoolExecutor");
executorPool = new ThreadPoolExecutor(1, 3, 1, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(1));
}
#PreDestroy
public void destroy() {
log.debug("Shuting down ThreadPoolExecutor");
executorPool.shutdown();
}