I happened to come across this article for killing a thread after some time using the Executor service : Killing thread after some specified time limit in Java
This is the code mentioned in the article :
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.invokeAll(Arrays.asList(new Task()), 10, TimeUnit.MINUTES); // Timeout of 10 minutes.
executor.shutdown();
Now that I have a runnable thread to be executed in my program .How do I kill this thread after some time using the above mentioned code?
Here's a part of my code which I have used for creating threads :
public static List<Thread> thread_starter(List<Thread> threads,String filename)
{ String text=read_from_temp(filename);
Runnable task = new MyRunnable(text);
Thread worker = new Thread(task);
worker.start();
// Remember the thread for later usage
threads.add(worker);
return threads;
}
public class MyRunnable implements Runnable {
MyRunnable(String text)
{
this.text=text;
}
#Override
public void run() {
/* other computation*/
}
I create multiple threads by calling thread_started() function .
Can anyone please help me on combining Executor Service with it . I tried a lot but couldn't find any way out !
In java, you can NOT kill a running thread directly. If you want to kill your running thread, you need a running flag in your task, check it in thread task, and set it outside. Eg:
MyRunnable task = ....;
......
task.running = false; //stop one task
public class MyRunnable implements Runnable {
public boolean running = true;
public void run() {
while(running){
.....
}
}
What you mentioned 'ExecutorService' is single thread 'ExecutorService', it would exec tasks one by one, what it do for timeout is just waiting a task completed and calculate/compare each task's time with timeout. You can find it in java's source code 'AbstractExecutorService.java'.
Related
I know that a java thread cannot be restarted. So when I submit more than one tasks to newSingleThreadExecutor, then how does it perform all tasks using single thread?
My understanding is that newSingleThreadExecutor will use maximum one thread at a time to process any submitted tasks. I guess same for newFixedThreadPool.
If a Thread cannot be restarted then for performing n tasks, n threads should be spawned. I think newSingleThreadExecutor, newFixedThreadPool will make sure that not many threads should be spawned at a same time, like we do without using ExecutorService (where we attach each task with a thread and start separately)
Here is code example
class Task implements Runnable {
public void run() {
System.out.println("ThreadID-" + Thread.currentThread().getId());
try {
Thread.sleep(100);
}
catch (InterruptedException e) {
}
}
}
public class SingleThreadExecutorTest {
public static void main(String[] args) {
System.out.println("ThreadID-" + Thread.currentThread().getId());
ExecutorService ex = Executors.newSingleThreadExecutor();
for (int i = 0; i < 10; i++) {
ex.execute(new Task());
}
}
}
The above code always prints the same ThreadID.
If I replace below line
Executors.newSingleThreadExecutor();
with
ExecutorService ex = Executors.newFixedThreadPool(2);
Then again it is able to perform all tasks using 2 Threads.
Only when I use
Executors.newCachedThreadPool();
I see different Thread IDs.
How does ExecutorService reuse a Thread?
Does it not let it reach to Dead State?
The ThreadPoolExecutor maintains some Worker threads, which work like this:
public class Demo {
public class Worker implements Runnable {
#Override
public void run() {
Runnable task = getTaskFromQueue();
while (task != null) {
task.run();
task = getTaskFromQueue(); // This might get blocked if the queue is empty, so the worker thread will not terminate
}
}
}
public static void main(String[] args) {
Worker worker = new Worker();
Thread thread = new Thread(worker);
thread.start();
}
}
When you submit a task to ThreadPoolExecutor which has a single Worker thread, the calling threads will put the task into a BlockingQueue on below condition:
the single Worker is busy
the BlockingQueue is not full
And when the Worker is free, it will retrieve new task from this BlockingQueue.
I am running simple thread which has run method as follows
public run()
while(!stopFlag){
// print something Line 1
// print something Line 2
// print something Line 3
// print something Line 4
}
If I run this thread through ExecutorService viz
ExecutorService exs = Executors.newFixedThreadPool(5);
exs.execute(new MyThread));
I stop the ExecutorService
exs.shutdown();
But this does not stop the thread as flag is not set to false. In another question related to same topic I was asked to properly handle InterruptedException which is caused when exs.shutdown() is called.
But in this case I am not doing any action that can throw InterruptedException.
What is the standard way to handle such case ?
Further question
Answer given by Sabir says "If your runnable doesn't respond well to interrupts, nothing can be done to stop it other than shutting down the JVM. ".This seems to be my case.
But how to introduce handling of InterruptedException; if I am not calling any method that throws interrupted exception?
If you are willing to shut your thread even if that flag remains true, you should use - ExecutorService.shutdownNow() method instead of ExecutorService.shutdown()
Quoting from Java Docs,
shutdown()
Initiates an orderly shutdown in which previously submitted tasks are
executed, but no new tasks will be accepted. Invocation has no
additional effect if already shut down.
This method does not wait for previously submitted tasks to complete
execution. Use awaitTermination to do that.
shutdownNow()
Attempts to stop all actively executing tasks, halts the processing of
waiting tasks, and returns a list of the tasks that were awaiting
execution.
This method does not wait for actively executing tasks to terminate.
Use awaitTermination to do that.
There are no guarantees beyond best-effort attempts to stop processing
actively executing tasks. For example, typical implementations will
cancel via Thread.interrupt, so any task that fails to respond to
interrupts may never terminate.
For standard way, I will quote from JDK example from ExecutorService interface,
Usage Examples
Here is a sketch of a network service in which threads in a thread pool service incoming requests. It uses the preconfigured Executors.newFixedThreadPool factory method: class NetworkService implements Runnable { private final ServerSocket serverSocket; private final ExecutorService pool;
public NetworkService(int port, int poolSize)
throws IOException {
serverSocket = new ServerSocket(port);
pool = Executors.newFixedThreadPool(poolSize); }
public void run() { // run the service
try {
for (;;) {
pool.execute(new Handler(serverSocket.accept()));
}
} catch (IOException ex) {
pool.shutdown();
} } }
class Handler implements Runnable { private final Socket socket; Handler(Socket socket) { this.socket = socket; } public void run() {
// read and service request on socket } }} The following method shuts down an ExecutorService in two phases, first by calling shutdown to reject incoming tasks, and then calling shutdownNow, if necessary, to cancel any lingering tasks: void shutdownAndAwaitTermination(ExecutorService pool) { pool.shutdown(); // Disable new tasks from being submitted try {
// Wait a while for existing tasks to terminate
if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {
pool.shutdownNow(); // Cancel currently executing tasks
// Wait a while for tasks to respond to being cancelled
if (!pool.awaitTermination(60, TimeUnit.SECONDS))
System.err.println("Pool did not terminate");
} } catch (InterruptedException ie) {
// (Re-)Cancel if current thread also interrupted
pool.shutdownNow();
// Preserve interrupt status
Thread.currentThread().interrupt(); } }}
Notice that there are no guarantees even with shutdownNow() .
EDIT : If I change your while(!stopFlag) to while(!Thread.currentThread().isInterrupted()) then thread with conditional loop get shutdown with shutdownNow() but not with shutdown() so thread gets interrupted with shutdownNow(). I am on JDK8 and Windows 8.1. I do have to put a sleep in main thread so that service can get time to set up the service and launch runnable. Thread gets launched, goes in while then stops when shutdownNow() is called. I don't get that behavior with shutdown() i.e. thread never comes out of while loop. So the approach to make your runnables responsible for interrupts should be there ,either by checking flags or handling exceptions. If your runnable doesn't respond well to interrupts, nothing can be done to stop it other than shutting down the JVM.
One good approach is shown here
well from your question I am assuming that you are trying to shutdown the process gracefully. In order to do so you need to register a shutdownHook to achieve it. Here is a sample code to achieve it.
package com.example;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ThreadManager {
public static void main(String[] args) {
MyThread myThread = new MyThread();
Runtime.getRuntime().addShutdownHook(new Thread(){
MyThread myThread = null;
#Override
public void run(){
System.out.println("Shutting down....");
this.myThread.stopProcess();
}
public Thread setMyThread(MyThread myThread){
this.myThread=myThread;
return this;
}
}.setMyThread(myThread));
ExecutorService exs = Executors.newFixedThreadPool(5);
myThread.setName("User");
exs.execute(myThread);
exs.shutdownNow();
}
}
And in MyThread.java will be look like following:-
package com.example;
public class MyThread extends Thread{
private boolean stopFlag;
#Override
public void run(){
while(!stopFlag){
System.out.println(this.getName());
}
}
public void stopProcess(){
this.stopFlag=true;
}
}
Now if you make a jar file of this code and run the in a Linux server to see how it is working, then follow these additional steps
Step 1> nohup java -jar MyThread.jar &
Press ctrl+c to exist
Now find the pid using following command
Step 2> ps -ef| grep MyThread.jar
Once you got the pid than execute the following command to stop gracefully
Step 3>kill -TERM <Your PID>
When you check the nohub.out file, the output will looks something like following
User
User
.
.
.
User
Shutting down....
User
.
.
Remember if you try to shutdown using kill -9 than you will never see the Shutting down.... message.
#Sabir already discuss the difference between shutdown and shutdownNow. However I will never recommend you to use interrupt call while the threads are running. It might cause memory leak in real time environment.
Upadte 1:-
public static void main(String[] args) {
MyThread myThreads[] = new MyThread[5];
ExecutorService exs = Executors.newFixedThreadPool(5);
for(int i=0;i<5;++i){
MyThread myThread = new MyThread();
myThread.setName("User "+i);
exs.execute(myThread);
myThreads[i] = myThread;
}
Runtime.getRuntime().addShutdownHook(new Thread(){
MyThread myThreads[] = null;
#Override
public void run(){
System.out.println("Shutting down....");
for(MyThread myThread:myThreads){
myThread.stopProcess();
}
}
public Thread setMyThread(MyThread[] myThreads){
this.myThreads=myThreads;
return this;
}
}.setMyThread(myThreads));
exs.shutdownNow();
}
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 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