This doc states that the JVM doesn't stop the JAVA process if there are non-daemon threads alive in the process.
When a Java Virtual Machine starts up, there is usually a single non-daemon thread (which typically calls the method named main of some designated class). The Java Virtual Machine continues to execute threads until either of the following occurs:
The exit method of class Runtime has been called and the security manager has permitted the exit operation to take place.
All threads that are not daemon threads have died, either by returning from the call to the run method or by throwing an exception that propagates beyond the run method.
I've tested this with starting a standalone Thread, an ExecutorService and a NioEventLoopGroup and it works as stated above.
But, for this sample Netty Echo Server, it states the following:
75 // Wait until the server socket is closed.
76 f.channel().closeFuture().sync();
If I remove this line the code terminates even though there are non-daemon threads alive in the process.
Can someone please explain why?
Related
A part of my dubbo configuration file:
<dubbo:protocol name="dubbo" dispatcher="all" threadpool="fixed" threads="100" />
According to dubbo documentation the config above means
A fixed size of thread pool and it creates threads when starts, never shut down.
But when I started the application then I use jstack to see if there are more than 100 threads, I found only about 40 threads and I didn't find any dubbo threads. So, what happened?
The thread pool that you create by declaring dubbo:protocol is not the only source of threads in the JVM. Normally JVM starts a number of utility threads so it can function properly and support various features e.g. finalizers, shutdown hooks, RMI, etc. jstack shows the thread names, most of them you should be able to google and understand their purpose.
Your dubbo thread pool will most likely spawn new threads only when handling the incoming requests.
Here's dubbo thread model(http://dubbo.apache.org/en-us/docs/user/demos/thread-model.html),there is a picture demonstrating dubbo thread model,you can see that only server has a thread pool,which means only dubbo provider has thread pool.because it needs to separate I/O thread from non I/O thread.
I'm interested in different approaches to gracefully shutting down a Java command line program. Sending a kill signal is not an option.
I can think of a few different approaches.
Open a port and wait for a connection. When one is made, gracefully shutdown.
Watch for a file to be created, then shutdown.
Read some input from the terminal, such as "execute shutdown".
The third one is not ideal, since there is often program output pumped to the screen. The first one takes too much effort (I'm lazy). Do most programmers use the second option? If not, what else is possible/elegant/simple?
you can try something like this:
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() { /*
my shutdown code here
*/ }
});
edit:
the shutdown hook will not perform the shutting down of the app. instead, it gives the developer a way to perform any clean-up that he/she wishes at shutdown.
from the JavaDoc for Runtime (a good read if you are planning to use this method):
A shutdown hook is simply an initialized but unstarted thread. When the virtual machine begins its shutdown sequence it will start all registered shutdown hooks in some unspecified order and let them run concurrently. When all the hooks have finished it will then run all uninvoked finalizers if finalization-on-exit has been enabled. Finally, the virtual machine will halt. ...
you could try to use Runtime.getRuntime().addShutdownHook() that should satisfy your requisite. In this way you can register an hook to do cleanups, in order to perfom a gracefull shutdown.
EDIT
http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Runtime.html#addShutdownHook(java.lang.Thread)
public void addShutdownHook(Thread hook)
Registers a new virtual-machine shutdown hook.
The Java virtual machine shuts down in response to two kinds of events:
The program exits normally, when the last non-daemon thread exits or when the exit (equivalently, System.exit) method is invoked, or
The virtual machine is terminated in response to a user interrupt, such as typing ^C, or a system-wide event, such as user logoff or system shutdown.
The benefit of the second option - checking for a file - over the first - listening on a port - is that you have some possibility of security.
You can set the permissions on the directory where the file is created so that only appropriate users can close the program. If you listen on a port any user can connect to it.
If you wanted to go with the socket version, it is very simple to implement. Here's the code:
ServerSocket server = new ServerSocket(8080);
System.out.println("Socket listening!");
server.accept();
System.out.println("Connection received!");
You could easily embed this code in a separate thread that you start with your program, and then have it modify global state to initiate shutdown.
The first two option is simple to implement. You could also use some JMX stuff (I don't know much about that). Tomcat uses the first approach and I applied 1 and 2 in two of my projects.
Consider having a JMX component. Then you can attach with JConsole either locally or over the network, and communicate with your component. Then the component can shut down the program properly.
With Java 6 u 10 or later, you can do the same with JVisualVM.
I would suggest to use the shutdown hook. It will allow your program do be controlled using standard OS tools. It also does not need any additional access to external resources (disk, ports, whatever).
i have a storm topology class which starts a kafka spout and bolts. This class is main class. I am trying to clean exit storm topology, so i have created a shutdown hook in side that topology main method.
//Shutdown hook
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
System.out.println("Inside shutdown hook.");
Utils.sleep(1000000);
cluster.killTopology("netra-fault-management");
cluster.shutdown();
logger.info("Shutting down Topology.");
}
});
Here is my shutdown hook which is in main method of tolpology class. I run it from command prompt and when i do ctrl+c it is expected to run this shutdown hook but it just closes and no hook code is called . Do any buddy have idea about that how to run it on ctrl+c (SIGINT).
With Runtime#addShutdownHook, it is possible.
The problem should be caused by Utils.sleep(1000000);. You should not "sleep" the shutdown thread as The Java Virtual Machine(and other applications) doesn't allow it. A shutdown hook is designed to be called when the application is about to be closed, to save important stuffs or unload resources, etc. The Java Virtual Machine will terminate after few seconds, even the thread isn't executed completely.
In rare circumstances the virtual machine may abort, that is, stop running without shutting down cleanly. This occurs when the virtual machine is terminated externally, for example with the SIGKILL signal on Unix or the TerminateProcess call on Microsoft Windows. The virtual machine may also abort if a native method goes awry by, for example, corrupting internal data structures or attempting to access nonexistent memory. If the virtual machine aborts then no guarantee can be made about whether or not any shutdown hooks will be run.
From JavaDoc for Runtime class. Sometimes the shutdown hook will not be called. Good luck!
See Nathan Marz commenting on a similar question years ago, I presume the behaviour has not changed:
https://groups.google.com/forum/#!topic/storm-user/A4-uFS6px2Y
Storm shuts down worker processes with SIGKILL, the JVM will not execute the shutdown hook under those circumstances (like it would for SIGINT).
As far as I understood from this and this, they've implemented a change allowing the shutdown hook to fire, but the hooks code is limited to one second, so OK for some scenarios. Hovewer, I didn't check personally as it's not enough for my case which is buffer upload. But there is alternative approach for me that I'm going to implement.
I am starting a java thread pool ThreadPoolExecutor (with a core pool size) inside a Weblogic server (WLS). To normally shutdown the pool i need to call shutdown() on this pool. But for reasons beyond my control I am not able to add any Application life cycle listener in this WLS , which means I dont have any shutdown hook to call this method.
So I am thinking to make the threads in pool as daemon threads , so that WLS JVM will not wait for these threads to finish when it is shutting down. Else JVM will not normally shutdown as core threads in pool are always running.
Is there any disadvantage of making threads in thread pool as daemon. I understand about daemon threads, when JVM exits, these threads will never be normally cleaned up and any thing running will not finish normally. This issue is only during shutdown stage.
Is there any other issue in making threads daemon in a thread pool ? (or a better way)
Given that you are in an application container, you may want to use Work Managers as #mprabhat suggests. But if you truly need threads that are under your control, you can still shut them down. WebLogic implements it's Application life cycle notification via shutdown hooks. And that mechanism is still available to you. You can use Runtime.addShutdownHook to register one. Don't forget that to do your work quickly. WebLogic has a timeout, so the shutdown sequence is basically:
Shutdown requested (either by System.exit() or a signal sent to the JVM process).
Your shutdown hooks and WebLogic's shutdown hooks execute.
After some timeout (5-10 sec I think) one of WebLogic's shutdown hooks calls System.halt().
The JVM terminates regardless of whether shutdown hooks have completed.
Please refer below link and I suggested Use java 7 thread concurrently
http://www.baptiste-wicht.com/2010/09/java-concurrency-part-7-executors-and-thread-pools/
enjoy
I have written a service for JIRA(a web application runs in tomcat) which runs periodically(say 1 hour). Basically, the service executes a system command thru runtime.exec(command) and parses the output generated by the command then updates a Lucene index with it, output will be huge.
The problems are:
1) If I shutdown tomcat with shutdown.sh while the above service is executing, the java(or the catalina) process is not getting killed. Both the java & child process are living for a while i.e., until the system command completes & service processes the output. But then the service fails to update the index leaving the index in an inconsistent state.
If I shutdown tomcat when the above service is not running, everything is good. I think, this is explained here. I am still not clear why JVM won't shutdown as the above service is running within tomcat?
Note that this is the only java app running on that machine.
2) Then, if I kill java using kill <pid>, both the java & child process are getting killed contradicting to this post.
Is this because the child process is sending output to parent(java) and once parent is killed, the child has no idea where to send the output and thus got killed ?
3) I tried to use shutdownhook as explained in this post, but that's not working for me. The code inside the shutdownhook is getting executed only after the java & child processes are done with their work. So, calling process.destroy() inside shutdownhook is not useful here.
This seems obvious, as the JVM is still running in my case, it won't call shutdownhooks until it starts it's shutdown sequence. Don't know how this worked for the other guy, I mean, how come the child process spawned by java is still running when JVM is down.
4) If I restart tomcat, new java process with different pid is generated.
Is it possible to stop the child process programmatically when tomcat is shutdown ?
Let me know if I am not clear with my explanation...
Here is the code that executes system command:
String command = getCommand();
File view = new File(viewPath);
Runtime runtime = Runtime.getRuntime();
try
{
final Process process = runtime.exec(command, null, view);
StreamReader errorStreamReader = new StreamReader(process
.getErrorStream());
Thread errorStreamThread = new Thread(errorStreamReader);
errorStreamThread.start();
revisions = parseRevisionLogs(process.getInputStream());
process.waitFor();
process.getInputStream().close();
process.getErrorStream().close();
process.getOutputStream().close();
}
The JVM will not shutdown unless the threads that are left are marked as "daemon". Any non-daemon user threads must finish before the JVM will exit. See this question. If your periodic tasks are not set with setDaemon(true) then they will have to finish before the JVM will exit. You have to call setDaemon before the process starts.
You should be able to make your periodic tasks to be daemon however you do have a race condition with JVM shutdown. You might consider having one daemon task doing the reading from the process but having a non-daemon task do the updating of the index which probably should not get killed while it is working.
Your non-daemon thread could then be sleeping, waiting for the load to finish, and testing to see if it should terminate with a volatile boolean field or other signal.
I'd suggest you to do the following.
Do not read the process' output directly from java. Instead redirect the output to file and read it from there when process is terminated. Wrap your command using batch file or shell script that stores the PID of separate process, so that you will be able to kill this process separately. Now add shutdown hook to tomcat that will run kill PID where PID is the process ID of separate process.
I believe this will work because now your tomcat and separate process are totally decoupled, so nothing bothers tomcat to shutdown. The same is about the process.
Good luck.
Are you doing a waitFor() on the process?
If so you could catch InterruptedException and to a p.destroy()