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.
Related
public class LambdaFunctionHandler implements RequestHandler<Object, String> {
#Override
public String handleRequest(Object input, Context context) {
Runnable runnable = new Runnable() {
#Override
public void run() {
System.out.println("Hello");
}
}
Thread thread1 = new Thread(runnable);
thread1.start();
Thread thread2 = new Thread(runnable);
thread2.start();
Thread thread3 = new Thread(runnable);
thread3.start();
Thread thread4 = new Thread(runnable);
thread4.start();
}}
I've tried normally and it works fine. but on the lambda function it will not work properly.
Thread is dying before the complete excution of threads. when return statement called it is automatically stopping threads.
Expected result
Hello
Hello
Hello
Hello
Actual Result
Hello
As people said in the comments, the problem is that you are not waiting for the threads to complete. You return from handleRequest() as soon as you're done starting threads. This tells Lambda that your execution is done, so it suspends your container before those threads have a chance to execute.
"Suspends your container" is the difference between running on Lambda and running locally. When you run locally the JVM actually exits, and it won't do so until all non-daemon threads have finished.
To ensure that all threads run, you need to call explicitly join them before returning from your handler function.
To help you understand how this works, you should also add some more debugging information (use System.err because it's unbuffered):
#Override
public String handleRequest(Object input, Context context) {
Runnable runnable = new Runnable() {
#Override
public void run() {
System.err.println("Hello from " + Thread.currentThread().getName());
}
};
Thread thread1 = new Thread(runnable);
thread1.start();
Thread thread2 = new Thread(runnable);
thread2.start();
Thread thread3 = new Thread(runnable);
thread3.start();
Thread thread4 = new Thread(runnable);
thread4.start();
thread1.join();
thread2.join();
thread3.join();
thread4.join();
System.err.println("handler function exiting");
}}
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.
Hey there i currently have a problem with my android app. I´m starting an extra thread via
implementing the Excecutor Interface:
class Flasher implements Executor {
Thread t;
public void execute(Runnable r) {
t = new Thread(r){
};
t.start();
}
}
I start my Runnable like this:
flasherThread.execute(flashRunnable);
but how can i stop it?
Ok, this is just the very basic threading 101, but let there be another example:
Old-school threading:
class MyTask implements Runnable {
public volatile boolean doTerminate;
public void run() {
while ( ! doTerminate ) {
// do some work, like:
on();
Thread.sleep(1000);
off();
Thread.sleep(1000);
}
}
}
then
MyTask task = new MyTask();
Thread thread = new Thread( task );
thread.start();
// let task run for a while...
task.doTerminate = true;
// wait for task/thread to terminate:
thread.join();
// task and thread finished executing
Edit:
Just stumbled upon this very informative Article about how to stop threads.
Not sure that implementing Executor is a good idea. I would rather use one of the executors Java provides. They allow you to control your Runnable instance via Future interface:
ExecutorService executorService = Executors.newSingleThreadExecutor();
Future<?> future = executorService.submit(flashRunnable);
...
future.cancel(true);
Also make sure you free resources that ExecutorService is consuming by calling executorService.shutdown() when your program does not need asynchronous execution anymore.
Instead of implementing your own Executor, you should look at ExecutorService. ExecutorService has a shutdown method which:
Initiates an orderly shutdown in which previously submitted tasks are executed, but no new tasks will be accepted.
I would suggest to use the ExecutorService, along with the Furure object, which gives you control over the thread that is being created by the executor. Like the following example
ExecutorService executor = Executors.newSingleThreadExecutor();
Future future = executor.submit(runnabale);
try {
future.get(2, TimeUnit.SECONDS);
} catch (TimeoutException ex) {
Log.warn("Time out expired");
} finally {
if(!future.isDone()&&(!future.isCancelled()))
future.cancel(true);
executor.shutdownNow();
}
This code says that the runnable will be forced to terminate after 2 seconds. Of course, you can handle your Future ojbect as you wish and terminate it according to your requierements
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.
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);