I am writing an application where it has two threads:
[1] main
[2] threadX
main thread is command line program and starts an application(mongodb) in background and then exits.
threadX is the Server part of my application which requires to be active as long as the application(mongodb) is running.
main takes two arguments: start and stop.
On start: it starts -> start mongod and threadX.
On stop: it starts -> kills mongod and (should)stops threadX.
But even after setting threadX as daemon it stops after main thread exits.
Proof:
public class Index {
public static void main(String [] args) {
Logger log = Logger.getLogger("Index logging");
try {
FileHandler logfile = new FileHandler("test.log");
logfile.setFormatter(new SimpleFormatter());
log.addHandler(logfile);
} catch (SecurityException | IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Thread daemonThread = new Thread() {
public void run() {
while (true) {
try {
log.log(Level.INFO,"Try block executed");
Thread.sleep(1000l);
} catch (Throwable t) {
t.printStackTrace();
}
}
}
#Override
public void finalize() {
log.log(Level.INFO,"Finalize method called");
}
};
daemonThread.setDaemon(true);
daemonThread.start();
try {
Thread.sleep(3500l);
} catch (Throwable t) {
//NO-OP
}
}
}
Output:
Apr 08, 2017 2:30:54 PM num.Index$1 run
INFO: Try block executed
Apr 08, 2017 2:30:55 PM num.Index$1 run
INFO: Try block executed
Apr 08, 2017 2:30:56 PM num.Index$1 run
INFO: Try block executed
Apr 08, 2017 2:30:57 PM num.Index$1 run
INFO: Try block executed
As you can see it does not continues to write logs after main exits
What i want is a thread that can be started in background and continue to run even when main thread exits and that thread can be stopped after i restart my app. Just like console applications which starts processes in background and quit leaving console available to user. The user can then use command to stop that background process.
Daemon threads do exit after the main method exits - if you do not want your thread to exit you should not make it a daemon thread.
Remove the line
daemonThread.setDaemon(true);
or change it to
daemonThread.setDaemon(false);
From the Javadoc of the setDaemon method:
The Java Virtual Machine exits when the only threads running are all
daemon threads.
Create a User Thread and not a Daemon Thread. Why do you need to set the Thread as Daemon?
JVM will not terminate a User Thread and it will wait for it to finish before exiting unlike Daemon Thread.
Hope this Helps
If I get right at what you're trying to accomplish: you want a program to control mongodb. Separate invocations of the program may have diffrent commands as their command line arguments.
In the case of "start": your app should start mongodb as a separate process so it can exit right after mongodb started. You wont need thread to keep mongodb running.
In the case of "stop": You'll have to connect to the mongodb process and tell it to shut down gracefully, wait for it to end and end your own program.
Related
I build a vehicle routing web application using optaplanner. When I tried to deploy my web application to a tomcat 8 server, and tried to run it from my web browser, it produces a warning in my tomcat log file. The log said something about my web application started a thread and failed to stop it, and probably will create a memory leak.
I have write a destroy method where my ExecutorService object will call shutdown method to make sure every thread it started was terminated. Here is my code :
public class OptimizerService implements IOptimizerService {
private ExecutorService executor;
#Override
public synchronized Boolean startSolving() throws Throwable {
executor = Executors.newFixedThreadPool(2);
...
}
...
// other methods
...
#PreDestroy
public synchronized void destroy() {
executor.shutdown();
}
}
But why I still got those warning in tomcat log?
Here is the tomcat log :
09-Jun-2017 08:25:56.377 WARNING [http-nio-18081-exec-295] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [VehicleRouting] appears to have started a thread named [drools-worker-4] 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)
java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
java.lang.Thread.run(Thread.java:745)
Any comment will be appreciated. Thanks and regards.
executor.shutdownNow(); interrupts the threads, but executor.shutdown(); does not. That latter just waits until the tasks are finished, good luck if you have a 2h solver running...
If the Solver detects that its thread is interrupted, it terminates (pretty much the same as a normal Termination), which in turns calls KieSession.dispose(). I presume dispose() takes care of any drools spawned threads.
That's the theory at least :)
I am using Quartz to run a job every hour. The servlet is running on Tomcat and I am using the ServletConextListener to listen for when the context is destroyed.
When I shut down tomcat, I get the message:
"appears to have started a thread named [MyScheduler_Worker-1] but has failed to stop it".
But later I see this message:
"[DEBUG] 28 Sep 11:45:26.671 AM MyScheduler_Worker-1 [org.quartz.simpl.SimpleThreadPool]
WorkerThread is shut down."
So is it safe to assume that there is no memory leak because of this thread?
Here is how my log looks:
{SEVERE: The web application [/*************] appears to have started a thread
named [MyScheduler_Worker-1] but has failed to stop it. This is very likely to c
reate a memory leak.
Sep 28, 2011 11:45:26 AM org.apache.catalina.loader.WebappClassLoader clearRefer
encesThreads
SEVERE: The web application [/*************] appears to have started a thread
named [MyScheduler_Worker-2] but has failed to stop it. This is very likely to c
reate a memory leak.
Sep 28, 2011 11:45:26 AM org.apache.catalina.loader.WebappClassLoader clearRefer
encesThreads
SEVERE: The web application [/*************] appears to have started a thread
named [MyScheduler_Worker-3] but has failed to stop it. This is very likely to c
reate a memory leak.
[DEBUG] 28 Sep 11:45:26.671 AM MyScheduler_Worker-2 [org.quartz.simpl.SimpleThre
adPool]
WorkerThread is shut down.
[DEBUG] 28 Sep 11:45:26.671 AM MyScheduler_Worker-1 [org.quartz.simpl.SimpleThre
adPool]
WorkerThread is shut down.
[DEBUG] 28 Sep 11:45:26.671 AM MyScheduler_Worker-3 [org.quartz.simpl.SimpleThre
adPool]
WorkerThread is shut down.
I know this is an old thread but in case others are looking for it.
We use to get the warnings of threads all the time until we added code to shutdown the Quartz Scheduler in our ServletContextListener.shutDown() method.
To shutdown the Scheduler:
quartzScheduler.shutdown();
int ct = 0;
// Try waiting for the scheduler to shutdown. Only wait 30 seconds.
while(ct < 30) {
ct++;
// Sleep for a second so the quartz worker threads die. This
// suppresses a warning from Tomcat during shutdown.
Thread.sleep(1000);
if (quartzScheduler.isShutdown()) {
break;
}
}
You can assume there is no memory leak because you see thread shutdown message. However, its possible to over come warning by clearing up threads before shut-down.
The shutdown-hook plugin catches the event of the JVM terminating, and calls shutdown on the scheduler.
Details:- http://quartz-scheduler.org/documentation/quartz-2.x/configuration/ConfigPlugins
Recently I was asked a question:
We've got the setPriority() method to set a thread for low priority.
Then why do we need a daemon thread. What's the difference between them?
Does marking a thread as daemon change its scheduling?
We've got the setPriority() method to set a thread for low priority. Then why do we need a daemon thread. What's the difference between them?
Typically, daemon threads have nothing to do with priority. The JVM shuts down when all user non-daemon threads finish. Marking a thread as a daemon thread means that it can be safely killed when the JVM exits.
Priority is about scheduling – about how often a thread gets a time slice in comparison to other threads that are ready to run. You can have low priority daemon threads or high priority daemon threads. You can have non-daemon threads that are also low and high priority. As an aside, thread priorities only apply in certain specific situations and on certainly architectures and as a Java thread expert, I never use them.
The concepts are orthogonal (mutually independent) – at least in the Java thread model.
In terms of when to make a thread daemon, I use daemon threads for any tasks that I don't care if they are interrupted when the JVM quits: keep-alive threads, statistics processors, log handling, etc.. Everything mission critical to the application is a non-daemon thread that has to be specifically interrupted or signaled to quit somehow.
A running daemon thread will not prevent your program from ending/exiting. However, all user threads must end before your program can exit. Priority may apply to either daemon or user thread. You may understand priority the same way you understand it in everyday life.
An example of
JVM shutting down when low priority thread completes. Despite Daemon threads still running
ALSO, shows that thread created by a daemon thread automatically becomes a daemon thread
package junk.daemon_thread_example;
class DeamonThreadPlus implements Runnable{
String id;
boolean createChild;
public DeamonThreadPlus(String id, boolean createChild){
this.id = id;
this.createChild = createChild;
}
#Override
public void run() {
// Parent daemon thread creates child daemon thread by default
if (createChild)
new Thread(new DeamonThreadPlus("DaemonChild", false)).start();
// This thread never self-completes (only terminates when process dies)
while (true){
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Daemon "
+ Thread.currentThread().isDaemon()
+ " id = " + id);
}
}
}
class UThread implements Runnable{
#Override
public void run() {
System.out.println("User thread start");
try {
Thread.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("User thread end (program exits)");
}
}
public class Caller{
public static void main(String[] args) {
Thread dt = new Thread( new DeamonThreadPlus("Daemon", true));
dt.setDaemon(true);
dt.start();
Thread ut = new Thread(new UThread());
ut.setPriority(Thread.MIN_PRIORITY);
ut.start();
}
}
The output is:
User thread start
Daemon true id = Daemon
Daemon true id = DaemonChild
Daemon true id = Daemon
Daemon true id = DaemonChild
Daemon true id = Daemon
Daemon true id = DaemonChild
Daemon true id = Daemon
Daemon true id = DaemonChild
User thread end (program exits)
Daemon true id = DaemonChild
Daemon true id = Daemon
If the Java runtime determines that the only threads running in an application are daemon threads (i.e., there are no user threads in existence) the Java runtime promptly closes down the application, effectively stopping all daemon threads dead in their tracks. In order for an application to continue running, it must always have at least one live user thread. In all other respects the Java runtime treats daemon threads and user threads in exactly the same manner.
except that in daemon thread .. when JVM terminate abruptly then finally blocks are not executed, stacks are not unwound – JVM just exits. Due to this reason daemon threads should be used sparingly and it is dangerous to use them for tasks that might perform any sort of I/O.
I am trying to implement simple file polling from one folder to another using camel 2.14 version. I have used pollEnrich with basic timer to poll every 30 seconds. But whenever I tried to stop the tomcat 7.0 server I am getting the logs as:
Catalina.logs
SEVERE: The web application [/CamelPoller] appears to have started a thread named [Camel (camel-1) thread #0 - timer://myTimer] but has failed to stop it. This is very likely to create a memory leak.
Aug 14, 2015 2:50:06 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
SEVERE: The web application [/CamelPoller] appears to have started a thread named [Camel (camel-1) thread #1 - file://D:/Input] but has failed to stop it. This is very likely to create a memory leak.
FilePollerDemo.java
public class FilePollerDemo {
public FilePollerDemo() {
CamelContext context = new DefaultCamelContext();
try {
context.addRoutes(new RouteBuilder() {
public void configure() {
from("timer://myTimer?period=30000")
.pollEnrich("file://D:/Input?fileName=test.txt")
.to("file://D:/Output");
}
});
context.start();
// context.stop();
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
I have commented out the context.stop(), because if I am using it, the file polling is not happening or if I used like this :
context.start();
thread.sleep(30000);
context.stop();
then the poller run only for once.
Please help me I am new to camel.
I have a gobbler that reads the output from a Process.
There is a case where we kill the process programatically using its PID and the external Windows taskkill command.
It is a 16-Bit DOS process
We taskkill because it is a DOS 16-bit process and Process.destroyForcibly() does not work with it because it resides in the ntvdm subsystem and the best way is to get the PID and use 'taskkill /T /F' which does indeed kill it and any children.
Normally, we have no problem with our DOS 16-bit (or 32 bit) processes. This one has some file locks in place. It is especially important that we ensure it is dead to have the OS release the locks.
We close all streams before and after the kill
Prior to calling taskkill, we attempt to flush and close all streams in an executor: in,out,err. After calling taskkill, we verify that all streams are closed by re-closing them.
We call Thread.interrupt() on all gobblers after the kill
Now, after the kill success, which is confirmed in the OS as well, the gobbler is still running and it does not respond to Thread.interrupt().
We even do a last-ditch Thread.stop (gasp!)
And furthermore, we have invoked Thread.stop() on it and it still stays waiting at the read stage ...
So, it seems, we are unable to stop the std-out and std-in gobblers on our Processes streams.
We know Thread.stop() is deprecated. To be somewhat safe, we catch ThreadDeath
then clean any monitors and then rethrow ThreadDeath. However,
ThreadDeath never in fact gets thrown and the thread just keeps on
waiting on inputStream.read ..
so Thread.stop being deprecated in this case is a moot point
... because it does not do anything.
Just so no one flames me and so that I have a clean conscience,
We have removed Thread.stop() from our production code.
I am not surprised that the Thread does not interrupt since that only happens on some InputStreams and not all reads are incorruptible. But I am surprised that the Thread will not stop when Thread.stop is invoked.
Thread trace shows
A thread trace shows that both main-in and main-er (the two outputs from the process) are still running even after the streams are closed, thread is interrupted and last ditch Thread.stop is called.
The task is dead, so why care about idle blocked gobblers?
It is not that we care that the gobblers won't quit. But we hate threads running that just pile up and clog the system. This particular process is called by a webserver and then .. it could amount to several hundred idle threads in a blocking state on dead processes...
We have tried launching the process two ways with no difference ...
run(working, "cmd", "/c", "start", "/B", "/W", "/SEPARATE", "C:\\workspace\\dotest.exe");
run(working, "cmd", "/c", "C:\\workspace\\dotest.exe");
The gobbler is in a read like this:
try (final InputStream is = inputStream instanceof BufferedInputStream
? inputStream : new BufferedInputStream(inputStream, 1024 * 64);
final BufferedReader br = new BufferedReader(new InputStreamReader(is, charset))) {
String line;
while ((line = br.readLine()) != null) {
lineCount++;
lines.add(line);
if (Thread.interrupted()) {
Thread.currentThread().interrupt();
throw new InterruptedException();
}
}
eofFound = true;
}
Our destroyer calls this on the gobbler thread after the taskkill:
int timeLimit = 500;
t.interrupt();
try {
t.join(timeLimit);
if (t.isAlive()) {
t.stop();
// we knows it's deprecated but we catch ThreadDeath
// then clean any monitors and then rethrow ThreadDeath
// But ThreadDeath never in fact gets thrown and the thread
// just keeps on waiting on inputStream.read ..
logger.warn("Thread stopped because it did not interrupt within {}ms: {}", timeLimit, t);
if (t.isAlive()) {
logger.warn("But thread is still alive! {}", t);
}
}
} catch (InterruptedException ie) {
logger.info("Interrupted exception while waiting on join({}) with {}", timeLimit, t, ie);
}
This is a snippet of the log output:
59.841 [main] INFO Destroying process '5952'
04.863 [main] WARN Timeout waiting for 'Close java.io.BufferedInputStream#193932a' to finish
09.865 [main] WARN Timeout waiting for 'Close java.io.FileInputStream#159f197' to finish
09.941 [main] DEBUG Executing [taskkill, /F, /PID, 5952].
10.243 [Thread-1] DEBUG SUCCESS: The process with PID 5952 has been terminated.
10.249 [main] DEBUG java.lang.ProcessImpl#620197 stopped with exit code 0
10.638 [main] INFO Destroyed WindowsProcess(5952) forcefully in 738 ms.
11.188 [main] WARN Thread stop called because it did not interrupt within 500ms: Thread[main-in,5,main]
11.188 [main] WARN But thread is still alive! Thread[main-in,5,main]
11.689 [main] WARN Thread stop because it did not interrupt within 500ms: Thread[main-err,5,main]
11.689 [main] WARN But thread is still alive! Thread[main-err,5,main]
Note: prior to calling taskkill, the Process std-out and std-err will not close. But they are closed manually after the taskkill (not shown in log because success).