I need to develop a maven plugin that can start an apache ftp-server, run it as a daemon (does not halt the build process) and stop it as another goal. Unfortunately my first attempt to with daemon threads fails:
public class FtpServerDaemon
{
public static void main(final String[] args) throws Exception
{
Thread thread = new Thread(new Runnable()
{
#Override public void run()
{
org.apache.ftpserver.main.Daemon.main(args);
}
});
thread.setDaemon(true);
thread.start();
Thread.sleep(10000);
}
}
The bad thing here is that the JVM does not terminate after 10 seconds but it runs indefinitely. If the Daemon.main is a black-box code (however the source is available), what can prevent the JVM from terminating in a daemon thread?
Agree with assylias and chrylis comments.
Instead of org.apache.ftpserver.main.Daemon.main(args); can you try some other code there? A loop that lasts more than the time the main thread sleeps should do, printing a number every n seconds or something.
I believe it must then terminate properly. Just to test whether the ftpserver is preventing the exit.
By the way, if a Daemon thread spawns a child thread, the child threads are automatically set as Daemon, right? So why this might be happening?
The FtpServer starts non-daemon threads and they are still running. If a thread is spawned from a daemon thread, the new thread will initially inherit the daemon status from its parent, but one can override it. E.g.:
Thread thread = new Thread(new Runnable()
{
#Override public void run()
{
Thread embeddedNonDaemon = new Thread(new Runnable()
{
#Override public void run()
{
while (true)
{
;
}
}
});
embeddedNonDaemon.setDaemon(false);
embeddedNonDaemon.start();
}
});
thread.setDaemon(true);
thread.start();
Thread.sleep(5000);
This code does not terminate, either.
Related
I have a main thread that creates several threads using Executors
ExecutorService executor = Executors.newFixedThreadPool(4);
Each thread has long running jobs (some legacy code from another team) which might run for hours.
Now I want to shutdown from the main thread using
executor.shutdownNow()
And I want the threads to be able to stop immediately, how could I do that?
In the thread, say we have such code:
public void run() {
doA();
doB();
doC();
...
...
}
Now my issue is, even if I called shutdownNow, the running thread will run to the end then stop. I'd like to know how to stop and exit.
It's a slightly tricky situation indeed!
Can we make use of a hook that the JDK has provided in the form of ThreadFactory that is consulted when the associated thread pool is creating a thread in which your legacy task will run? If yes, then why not make your legacy code run in a daemon thread? We know that the JVM exits when the last non-daemon thread exits. So, if we make each thread that the thread pool uses to run your legacy tasks a daemon thread, there is a chance that we can make the shutdownNow() call more responsive:
public class LegacyCodeExecutorEx {
public static void main(String[] args) throws InterruptedException {
ExecutorService executor = Executors.newFixedThreadPool(2, new DaemonThreadFactory());
executor.submit(new LegacySimulator());
Thread.sleep(1000);
executor.shutdownNow();
}
static class LegacySimulator implements Runnable {
private final AtomicLong theLong;
LegacySimulator() {
theLong = new AtomicLong(1);
}
#Override
public void run() {
for (long i = 10; i < Long.MAX_VALUE; i++) {
theLong.set(i*i);
}
System.out.println("Done!");
}
}
static class DaemonThreadFactory implements ThreadFactory {
#Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r);
t.setName("Daemon Thread");
t.setDaemon(true);
return t;
}
}
}
If you play with setDaemon(true) line, you will see that this code either responds to the exit of the main thread (which is non-daemon) either immediately or takes its own sweet time to finish the task.
Is making your legacy-code-running threads daemon threads a possibility? If yes, you could give this a try.
You need to include a flag in the Runnable object instantiation that checks between tasks whether you need to stop or not.
public void run() {
if(timeToShutdown) return;
doA();
if(timeToShutdown) return;
doB();
/*etc*/
}
Threads in Java operate at a (relatively) low level. Short of directly shutting down the entire JVM, the only way to manually force the stop of a Thread is using Deprecated behavior from Java 1.0/1.1, which pretty much noone wants you to use.
I'm invoking thread.In that thread there is while(true) condition because of that I'm not able to execute next thread.
Snippet is here
ASubscriber aSubscriber=new ASubscriber();
aSubscriber.run();
System.out.println("Starting Subscriber Thread");
BSubscriber bSubscriber=new BSubscriber();
bSubscriber.run();
In each of run method of ASubscriber and Bsubscriber has below Code :
#Override
public void run() {
while (true)
{
//I'm going some task
}
}
aSubscriber.run();
System.out.println("Starting Subscriber Thread");
Thread#run does not start threads.
It just runs them on the current thread.
You probably want
aSubscriber.start();
I have the following code:
public class Driver {
private ExecutorService executor = Executors.newCachedThreadPool();
public static void main(String[] args) {
Driver d = new Driver();
d.run();
}
private void run() {
final Timer timer = new Timer();
final TimerTask task = new TimerTask() {
#Override
public void run() {
System.out.println("Task is running!");
}
};
Runnable worker = new Runnable() {
#Override
public void run() {
timer.scheduleAtFixedRate(task, new Date(), 5 * 1000);
}
};
Runtime.getRuntime().addShutdownHook(new Thread() {
#Override
public void run() {
System.out.println("Shutdown hook is being invoked!");
try {
if(executor.awaitTermination(20, TimeUnit.SECONDS))
System.out.println("All workers shutdown properly.");
else {
System.out.println(String.format("Maximum time limit of %s reached " +
"when trying to shut down workers. Forcing shutdown.", 20));
executor.shutdownNow();
}
} catch (InterruptedException interrupt) {
System.out.println("Shutdown hook interrupted by exception: " +
interrupt.getMessage());
}
System.out.println("Shutdown hook is finished!");
}
});
executor.submit(worker);
System.out.println("Initializing shutdown...");
}
}
When this runs I get the following console output:
Initializing shutdown...
Task is running!
Task is running!
Task is running!
Task is running!
Task is running!
Task is running!
Task is running!
... (this keeps going non-stop)
When I run this, the application never terminates. Instead, every 5 seconds, I see a new println of "Task is running!". I would have expected the main thread to reach the end of the main method, print "Initializing shutdown...", invoked the added shutdown hook, killed the executor, and finally print out "Shutdown hook is finished!".
Instead, "Task is running" just keeps getting printed and the program never terminates. What's going on here?
I am no expert but AFAIK you must have all non-Daemon threads terminated in order for the shutdown hook to “kick in”.
In the original example you have 3 non-Daemon:
The thread of “Main” – this is the only non-Daemon you want here..
The thread that runs the “TimerTask” – it is created by the “Timer” and you covered it by fixing to Timer(true)
The thread that runs the “worker” – it is created by the “executor” and in order for the “executor” to create Daemon threads you should create a ThreadFactory. (at least this is the way I know; there might be other ways...)
So I think what you should do is to create a ThreadFactory and use it when initializing the “executor”.
Create a class that will be the ThreadFactory:
private class WorkerThreadFactory implements ThreadFactory {
#Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r, "Worker");
t.setDaemon(true);
return t;
}
}
-- the important line is the setDaemon of course :)
Pass an instance of it as a parameter to the newCachedThreadPool method:
private ExecutorService executor = Executors.newCachedThreadPool(new WorkerThreadFactory());
Applying these 2 changes did the trick for me and I got to:
Maximum time limit of 20 reached when trying to shut down workers. Forcing shutdown.
Shutdown hook is finished!
Hope it helps,
Izik
golan2#hotmail.com
It is not shutting down because Timer() creates and starts a non-daemon thread ... which is then never stopped.
There are two things that can cause the JVM to shutdown of its own accord:
A call to System.exit() (or Runtime.halt())
The termination of the last remaining non-daemon thread.
Since you have created a second non-daemon thread (in addition to the thread that is running main()) the second condition won't be met.
I want to achieve the following: When my application starts, the main thread will start 1+ worker threads that should run in the background, and periodically do things behind the scenes. These should not block the main thread: once main starts the workers, it continues doing its own thing until:
The main thread finishes (normal application termination) - in the case of a command-line utility this is when the end of the main(String[]) method is reached; in the case of a Swing GUI it could be when the user selects the File >> Exit menu, etc.
The operating system throws a kill command (SIGKILL, etc.)
An unexpected, uncaught exception occurs in the main thread, effectively killing it (this is just an unpolite version of #1 above)
Once started/submitted from the main thread, I want all the worker threads (Runnables) to essentially have their own life cycle, and exist independently of the main thread. But, if the main thread dies at any time, I want to be able to block (if at all possible) the main thread until all the workers are finished shutting down, and then "allow" the main thread to die.
My best attempt so far, although I know I'm missing pieces here and there:
public class MainDriver {
private BaneWorker baneWorker;
private ExecutorService executor = Executors.newCachedThreadPool();
public static void main(String[] args) {
MainDriver driver = new MainDriver();
driver.run();
// We've now reached the end of the main method. All workers should block while they shutdown
// gracefully (if at all possible).
if(executor.awaitTermination(30, TimeUnit.SECONDS))
System.out.println("Shutting down...");
else {
System.out.println("Forcing shut down...");
executor.shutdownNow();
}
}
private void run() {
// Start all worker threads.
baneWorker = new BaneWorker(Thread.currentThread());
// More workers will be used once I get this simple example up and running...
executor.submit(baneWorker);
// Eventually submit the other workers here as well...
// Now start processing. If command-line utility, start doing whatever the utility
// needs to do. If Swing GUI, fire up a parent JFrame and draw the application to the
// screen for the user, etc.
doStuff();
}
private void doStuff() {
// ??? whatever
}
}
public class BaneWorker implements Runnable {
private Timer timer;
private TimerTask baneTask;
private Thread mainThread;
public BaneWorker(Thread mainThread) {
super();
this.mainThread = mainThread;
}
#Override
public void run() {
try {
timer = new Timer();
baneTask = new TimerTask() {
#Override
public void run() {
System.out.println("When the main thread is ashes...");
}
};
// Schedule the baneTask to kick off every minute starting now.
timer.scheduleAtFixedRate(baneTask, new Date(), 60 * 1000);
} catch(InterruptedException interrupt) {
// Should be thrown if main thread dies, terminates, throws an exception, etc.
// Should block main thread from finally terminating until we're done shutting down.
shutdown();
}
}
private void shutdown() {
baneTask.cancel();
System.out.println("...then you have my permission to die.");
try {
mainThread.join();
} catch(InterruptedException interrupt) {
interrupt.printStackTrace;
}
}
}
Am I on-track or way off-base here? What do I need to change to make this work the way I need it to? I'm new to Java concurrency and am trying my best to use the Concurrency API correctly, but stumbling around a bit. Any ideas? Thanks in advance!
The main thread must signal the worker threads to terminate (generally this is achieved just by using a flag) and then it should call join on every thread to wait for their termination. Have a look here: Java: How to use Thread.join
You can use Runtime.addShutdownHook to register an un-started thread that is executed when a JVM is terminated, the system is shutting down etc. This code can do some cleanup itself, or perhaps notify running daemon threads to finish their work. Any such cleanup code must be relatively fast, because on many systems programs have only a limited time to do cleanup before they're forcibly terminated.
Perhaps you could also consider making your background thread daemon threads. Then they will not block the JVM when main finishes and will be still running during the clean-up phase.
Note that you can't intercept SIGKILL - this signal is designed to be unavoidable and immediate. But it should work with SIGTERM, SIGHUP and similar signals.
Update: You can easily create ExecutorServices that run daemon threads. All you need is to create a proper ThreadFactory:
public static class DaemonFactory
implements ThreadFactory
{
#Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r);
t.setDaemon(true);
return t;
}
}
than you create an ExecutorService like
public static void main(String argv[])
throws Exception
{
ExecutorService es
= Executors.newCachedThreadPool(new DaemonFactory());
// ^^^^^^^^^^^^^^^^^^^
es.submit(new Callable<Object>() {
public Object call() throws Exception {
Thread.sleep(100);
System.err.println("Daemon: " +
Thread.currentThread().isDaemon());
return null;
}
});
// Without this, JVM will terminate before the daemon thread prints the
// message, because JVM doesn't wait for daemon threads when
// terminating:
es.awaitTermination(3, TimeUnit.SECONDS);
}
Concerning Thread.join(), you shouldn't try to use it on threads managed by an ExecutorService. It's the responsibility of the executor to manage them. You have no reliable way how to enumerate its threads, the executor can create and destroy threads depending on its configuration etc. The only reliable way is to call shutdown(); and then awaitTermination(...);.
If SIGKILL is a unix "kill -9" there's nothing you can do about it.
For graceful exits, use a try/catch/finally in your main. The catch will catch your exceptions and allow you to do what needs to be done (recover? abort?) The finally will give you the hook to spin down your threads gracefully.
Reviewing your code quickly, I don't see where you're keeping track of your thread instances. You'll need those if you're going to tell them to spin down.
psuedocode:
static Main(...) {
ArrayList threads = new ArrayList();
try {
for (each thread you want to spin up) {
threads.add(a new Thread())
}
}
catch { assuming all are fatal. }
finally {
for(each thread t in threads) {
t.shutdown();
t.join(); /* Be prepared to catch (and probably ignore) an exception on this, if shutdown() happens too fast! */
}
}
When my application is ready to exit, either by closing a window or invoking the System.exit() method. Do I have to manually stop the threads I may have created or will Java take care of that for me?
In cases you use System.exit(). All the threads will stop whether or not they are daemon.
Otherwise, the JVM will automatically stop all threads that are daemon threads set by Thread.setDaemon(true). In other words, the jvm will only exit when only threads remaining are all daemon threads or no threads at all.
Consider the example below, it will continue to run even after the main method returns.
but if you set it to daemon, it will terminate when the main method (the main thread) terminates.
public class Test {
public static void main(String[] arg) throws Throwable {
Thread t = new Thread() {
public void run() {
while(true) {
try {
Thread.sleep(300);
System.out.println("Woken up after 300ms");
}catch(Exception e) {}
}
}
};
// t.setDaemon(true); // will make this thread daemon
t.start();
System.exit(0); // this will stop all threads whether are not they are daemon
System.out.println("main method returning...");
}
}
If you want stop threads before exit gracefully, Shutdown Hooks may be a choice.
looks like:
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
//Stop threads }
});
See: hook-design