I was doing a sort of research in which I want to make a user thread as a daemon thread ,Thread.setDaemon(true) makes a Thread daemon, but as we knowDaemon Threads are suitable for doing background job, so I want to link my this thread to any background daemon thread so that my daemon thread can provide some services to that thread and it should end when that daemon threads end, although I have created the daemon thread but please advise how I would provide the services through my daemon thread to any existing daemon thread and then it should end up at last, please advise.
Thread daemonThread = new Thread(new Runnable(){
#Override
public void run(){
try{
while(true){
System.out.println("Daemon thread is running");
}
}catch(Exception e){
}finally{
System.out.println("Daemon Thread exiting"); //never called
}
}
}, "Daemon-Thread");
daemonThread.setDaemon(true); //making this thread daemon
daemonThread.start();
}
I don't know exactly what you mean but I would change
while(true){
to
while(!Thread.currentThread.isInterrupted()){
This will allow your thread to stop when interrupted.
I would also consider using an ExecutorService as this makes it easier to pass work to another thread and shut it down when you are finished.
ExecutorService service = Executors.newSingleThreadExecutor(new ThreadFactory() {
#Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r, "worker");
t.setDaemon(true);
return t;
}
});
service.submit(new Runnable() { /* task for this thread to perform */ });
service.shutdown(); // to stop it.
Related
In python I can set a thread to be a daemon, meaning if parent dies, the child thread automatically dies along with it.
Is there an equivalent in Java?
Currently I am starting a thread like this in Java, but the underlying child thread does not die and hang even if main thread exits
executor = Executors.newSingleThreadExecutor();
executor.submit(() -> {
while (true) {
//Stopwatch stopwatch = Stopwatch.createStarted();
String threadName = Thread.currentThread().getName();
System.out.println("Hello " + threadName);
try {
Thread.sleep(1*1000);
} catch (InterruptedException e) {
break;
}
}
});
When you're interacting with bare Thread you can use:
Thread thread = new Thread(new MyJob());
thread.setDaemon(true);
thread.start();
In your example, there's ExecutorService that needs to be provided with ThreadFactory which should do the similar job - like this:
Executors.newSingleThreadExecutor(new ThreadFactory() {
#Override
public Thread newThread(Runnable r) {
Thread thread = new Thread(r);
thread.setDaemon(true);
return thread;
}
});
I would also recommend using Guavas ThreadFactoryBuilder:
Executors.newSingleThreadExecutor(
new ThreadFactoryBuilder()
.setDaemon(true)
.build()
);
It eases setting the most common thread properties and allows for chaining multiple thread factories
update
As Slaw and Boris the Spider rightfully noticed - you have mentioned the behavior that would cause killing child-thread when parent-thread dies. There's nothing like that either in Python or Java. Daemon threads will be killed when all other non-daemon threads exited.
In Java library thread pool implementations, usually shutting down a pool means:
-stop accepting new tasks
-previously submitted tasks are executed
-all pool threads are terminated
Regarding the last point, how would you stop a pool thread that could potentially try to take a new task, after it has been stopped?
My threads do something like this (in java pseudo code):
public void run() {
while(!isStopped) {
Task task = taskQueue.take(); //line1
task.run(); //line2
}
}
and have a method stop:
public synchronized void stop(){
isStopped = true;
this.interrupt();
}
In my thread pool class, I have a method stop:
public synchronized void shutdown(){
this.isShutdown = true; //to stop the whole pool
for(PoolThread thread : threads)
thread.stop();
}
The point is, if a thread reaches line 1, isStopped was false, but at that same moment it could be set to true by the pool class. How do I remember that I should stop the thread again? Does calling interrupt suffice?
Send the shutdown messages through the task queue:
static Task stop = // some special value
public void run() {
while (true) {
Task task = taskQueue.take();
if (task == stop) {
break;
}
task.run();
}
}
and in shutDown:
public synchronized void shutdown(){
if (isShutdown) {
return;
}
this.isShutdown = true;
for(PoolThread thread : threads) {
taskQueue.put(PoolThread.stop);
}
}
With a number of shutdown messages in the queue equal to the number of threads, once all work is completed, the threads will each take a shutdown message and shut down. (Note that we don't need to care about which thread gets which shutdown message.)
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.
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.
Trying to interrupt a running thread, in this example, t1, which is executed by a thread in a thread pool.
t2 is the one that sends the interrupt.
I'm unable to stop the running t1, t1 does not get InterruptedException.
What am I missing?
Executor exec1 = Executors.newFixedThreadPool(1);
// task to be interrupted
Runnable runnable = new Runnable() {
#Override
public void run() {
try {
System.out.println("starting uninterruptible task 1");
Thread.sleep(4000);
System.out.println("stopping uninterruptible task 1");
} catch (InterruptedException e) {
assertFalse("This line should never be reached.", true);
e.printStackTrace();
}
}
};
final Thread t1 = new Thread(runnable);
// task to send interrupt
Runnable runnable2 = new Runnable() {
#Override
public void run() {
try {
Thread.sleep(1000);
t1.interrupt();
System.out.println("task 2 - Trying to stop task 1");
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
Thread t2 = new Thread(runnable2);
exec1.execute(t1);
t2.start();
t2.join();
Seems like you misunderstand threads and Executors. You create two threads object for two runnables, but start only one of them (t2), t1 you pass to Executor to run inside it. But executor does not need Thread to be supplied -- it just need Runnable implementation. Executor itself is a thread pool (usually, but it's not required), and it just creates (and pool) threads inside it. It sees you thread just as simple Runnable (which is Thread implements). So you actualy send interrupt to the thread which was never started.
If you really want to make your code works, you should remove Executor, and just start both threads explicitly.
Your mistake is that you're trying to execute a Thread on a ThreadPool.
This appears to work, because Thread happens to implement Runnable, but because the thread is only being used as a Runnable and is not started as a Thread, calling methods like #interrupt() won't have the desired effect.
If you still need to use a thread pool, you should instead look into using a class like FutureTask. Wrap your Runnable in a FutureTask, and then submit the task to a thread pool. Then, when you want to interrupt the task, call futureTask.cancel(true).
The problem is that you can never really know which thread would be used by the Executor to run your task.
Even though you have submitted a Thread object, The Executor will use the thread created by the fixed thread pool. Thus the thread with reference t1 is not the thread in which your task is going to be executed. so calling t1.interrupt() is not going to do anything.
To properly way to do this is to use an ExecutorService and use the submit() to submit a Runnable/Callable object. This will return a Future which exposes a cancel() method which can be used to cancel the task.
Calling Thread.interrupt does not necessarily throw an InterruptedException. It may just set the interrupted state of the thread, which can be polled by Thread.interrupted() or Thread.isInterrupted.
See http://download.oracle.com/javase/1.4.2/docs/api/java/lang/Thread.html#interrupt() for more details.
To interrupt the executor thread ,
final ExecutorService exec1 = Executors.newFixedThreadPool(1);
final Future<?> f = exec1.submit(runnable);
...
f.cancel(true);