When I create a thread by calling ScheduledExecutorService.schedule(), it never terminates after executing the scheduled task.
For example the following program never quits:
public static void main(String[] args) {
ScheduledFuture scheduledFuture =
Executors.newSingleThreadScheduledExecutor().schedule(new Callable() {
public Void call() {
doSomething();
return null;
}
}, 1, TimeUnit.SECONDS);
}
public static void doSomething() {
}
Is this a JDK bug, or did I just miss something?
A scheduled task is either being executed or is waiting to be executed.
If the task is waiting to be executed, future.cancel() will prevent it from being executed (both cancel(true)/cancel(false)).
If the task is already being executed, future.cancel(false) will have no effect. future.cancel(true) will interrupt the thread that is executing that task. Whether this will have any effect is up to you, who will implement that task. A task may or may not respond to interruption depending on the implementation.
In order to make your task responsive to cancellation, you must implement doSomething() so that it will respond to interruption.
There are basically two way to do this:
1.Check interruption flag in your logic
public void doSomething(){
stuff();
//Don't use Thread.interrupt()
if(Thread.currentThread().isInterrupted()){
// We have an interruption request, possibly a cancel request
//Stop doing what you are doing and terminate.
return;
}
doLongRunningStuff();
}
You must occasionally check for the interruption flag, and if interrupted, stop what you are doing and return. Be sure to use Thread.isInterrupted() and not Thread.interrupt() for the check.
2.Act upon Interrupted exception
public void doSomething(){
try{
stuff();
}catch(InterruptedException e){
// We have an interruption request, possibly a cancel request
// First, preserve Interrupted Status because InterruptedException clears the
// interrupted flag
Thread.currentThread.interrupt();
// Now stop doing your task and terminate
return;
}
doLongRunningStuff();
}
When you have any method that throws InterruptedException, be sure to stop what you doing and terminate when one is thrown.
Once you implement your methods in this way, you can call future.cancel(true) to cancel the execution of a running task.
Your program never terminates because you create a ScheduledExecutorService, which holds a thread pool, but you never shut down the service. Therefore, the user threads in the thread pool are never terminated, and hence the VM keeps running forever.
To solve this problem, you need to call a shutdown() on the executor service. This can even be done directly after scheduling the task you want to execute:
public static void main(String[] args) {
ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
ScheduledFuture scheduledFuture = executorService.schedule(new Callable() {
public Void call() {
doSomething();
return null;
}
}, 1, TimeUnit.SECONDS);
executorService.shutdown();
}
This will execute the scheduled task normally and then terminate the thread in the pool.
You need to call scheduledExecutorService.shutdown() to stop the execution. Otherwise it is restarted every second.
(EDITED: see comments)
Related
In the book, Java Concurrency in Practice by Brian Goetz et al, the example on page 141 (2006):
7.5: Using interruption for cancellation.
class PrimeProducer extends Thread {
}
...
public void cancel() { interrupt(); }
The confusing thing is that the book states that Threads should implement an Interruption Policy, while Runnable / Callable tasks should implement a Cancellation Policy.
Yet here we are with a cancel() method inside of a Thread object. What's up with that? A few pages before, an example with Runnable is given (7.1) with cancel(). In the case of tasks, I would expect to see a qualified interrupt() like this:
public void cancel() { Thread.currentThread().interrupt(); }
Extra, semi-relevant information
I am using an ExecutorService, so I deal with tasks (not threads--except for a thread factory for the ExecutorService), but I could not find any could examples of a full ExecutorService shutdown (of many threads) in the book.
My methods for starting tasks and stopping them are:
Map<CancellableRunnable, Future<?>> cancellableFutures = new HashMap<>(); // keep track of refs to tasks for stop()
public void init() {
Future<?> future = myExecutorService.submit(myTask);
cancellableFutures.put(myTask, future);
}
public void stop() {
for (Future task : cancellableFutures.values()) {
task.cancel(true); // also a confusing step. Should it be cancel() on Future or cancel() on task (Runnable/Callable)?
}
}
The confusing thing is that the book states that Threads should implement an Interruption Policy
Right,
class MyThread extends Thread {
#Override
public void interrupt() { ... }
}
while Runnable / Callable tasks should implement a Cancellation Policy.
Right,
// FutureTask = Runnable (for run) + Future<Void> (for cancel(boolean))
class MyTask extends FutureTask<Void> {
#Override
public boolean cancel(boolean mayInterruptIfRunning) { ... }
#Override
public void run() { ... }
}
Yet here we are with a cancel() method inside of a Thread object.
Thread is both Thread and Runnable, so both interrupt (to interrupt this thread) and cancel (to cancel this task, the task currently being run by this thread) should be defined.
public class Thread implements Runnable { ... }
The PrimeProducer example is a bit confusing because it assumes the task defined in PrimeProducer will be used outside PrimeProducer.
class PrimeProducer extends Thread {
public void run() {
try {
BigInteger p = BigInteger.ONE;
while (!Thread.currentThread().isInterrupted())
queue.put(p = p.nextProbablePrime());
} catch (InterruptedException consumed) {
/* Allow thread to exit */
}
}
public void cancel() { interrupt(); }
}
It's very reasonable and accurate since we can do
Runnable runnable = new PrimeProducer();
new Thread(runnable).start();
It's rarely the case, though. It's highly likely we would simply go with
new PrimeProducer().start();
which would make the task we define in run context-aware and Thread.currentThread().isInterrupted() and isInterrupted() would mean the same. That's what your confusion over Thread.currentThread().interrupt() and interrupt() comes from.
In the case of tasks, I would expect to see a qualified interrupt() like this:
public void cancel() { Thread.currentThread().interrupt(); }
That interrupts your own thread, not the thread running the task. There's no point in interrupting yourself if you want something else to stop what it's doing: you can simply stop what you're doing instead.
(You might interrupt the current thread, for example, if you have just caught an InterruptedException, and want to preserve the fact that the thread was interrupted. But you don't use this as a mechanism to start the interruption).
To correctly close a thread, you have to ask it to close itself by calling thread.interrupt() and the thread should periodically check thread.isInterrupted() method.
See more details in official documentation.
For your example, you have an ExecutorService myExecutorService. To close all submitted threads (along with thread pool itself), you could call myExecutorService.shutdown(). As a result, the thread pool calls thread.interrupt() for all threads.
To stop required threads only, you do correct calling future.cancel(true). In this case, your thread pool will be alive and will able to submit another task.
I have a thread, inside its making a database call that sometimes hangs, normally timeout should be handle in the client library, but in this case the client library doesn't handle it correctly so I have to add an extra scheduled job to cancel the thread that is making db call if it takes too long to avoid back pressure.
Right now I am terminating the thread through
final Future handler = executor.submit(new MyTask());
executor2.schedule(new Runnable(){
public void run(){
handler.cancel(true);
}
}, 3, TimeUnit.SECONDS);
Is there a proper way to interrupt a thread without TimeUnit.MILLISECONDS.sleep(1); ? Adding sleep seems hacky
#Override
public Boolean call() {
try {
// Sometimes hangs
db.call();
// Need it to be here to call InterruptedException
TimeUnit.MILLISECONDS.sleep(1);
return true;
} catch (InterruptedException e) {
return false;
}
}
Is there a proper way to interrupt a thread without TimeUnit.MILLISECONDS.sleep(1); ?
This doesn't interrupt a thread. It merely checks if the thread has been interrupted, either before or during the sleep, and throws an InterruptedException if it was.
If you want to interrupt a thread, use:
t.interrupt();
If you want to check if the current thread has been interrupted, use:
Thread.interrupted()
Note that this clears this interrupted state: use Thread.currentThread().isInterrupted() to check without clearing the state.
As of Java 9, you can use CompletableFuture.orTimeout:
Future<?> handler = CompletableFuture.runAsync(new MyTask())
.orTimeout(3, TimeUnit.SECONDS);
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 situation where I'm using a Thread, she call a method that will do multiple processes, I need to use a "cancel" button in which you have to stop the thread, I not can use: "while" ,to verify that it was canceled because it not has loop in this process.
Ex:
Task<Void> task = new Task<Void>() {
#Override
protected Void call() throws Exception {
controller = new FirstEtapaController();
execProcess();
return null;
}
};
new Thread(task).start();
Call Method
private void execProcess() {
Thread thread = new Thread(new Runnable() {
public void run() {
getController().execMhetod();
refreshTable();
}
});
thread.start();
thread.join();
};
Ie, I need to stop this process, even when the "ExecMethod" already running, it will take minutes, so I've gotta stop it and not have to wait for him to finish so that , others do not continues.
Remembering that this process will do iteration with my DAO.
The only way (well behaved way) is to add logic points in you spawned threads to check for an interrupted state. You can choose to use the built-in Thread.interrupt() mechanisms, or add your own logic using some form of thread-safe variable (an AtomicBoolean?) or a Semaphore of some sort.
If you use the Thread.interrupt() then your child processes will throw an InterruptedException when they encounter certain conditions, like Thread.wait() and other methods which require synchronization or use the java.util.concurrent.* classes.
You will need to (should already be) handle the InterruptedExceptions in the threads anyway, but perhaps you will need to put regular 'checks' in your child processes to look for the interrupted state anyway (can use Thread.isInterrupted() )
It is worth reading this Handling InterruptedException in Java
If instead of a raw Thread if you use an ExecutorService you'll end up with lots of additional methods/levers to control your threads, one of which is shutdownAll() which uses Thread.interrupt() to kill your thread and lets you check thread status via isTerminated()
Your user interface does not have to wait for the worker thread to finish, so don't worry too much about that.
Alas, Thread.destroy() and Thread.stop() are deprecated, due to bad implementations. I don't think there is a good "sig-kill" type of substitute for Java threads. You are going to have to recode the worker to check an abort flag of some kind, if it matters much. Otherwise, just let it waste a little CPU. ("you can't cancel that Save -- I've already done it!", in effect)
Whether or not a task can be canceled really depends on its implementation. Typically it intermittently checks a flag whether it should continue or not.
You can implement such a flag yourself, and a method to set it :
private volatile boolean shouldStop;
public void cancel() {
shouldStop = true;
}
#Override
public void run() {
while (!shouldStop) {
// do work
}
}
But threads already come with a flag : the interrupted flag. And while it is not necessarily used for canceling a thread, it is typical to use it for exactly that purpose. In fact the standard ExecutorService implementations will try to cancel their threads by interrupting them.
Aside from that several blocking methods (methods that put a thread in BLOCKED or WAITING state) will throw an InterruptedException when the thread is interrupted, at which point they become RUNNABLE again. This is something the previous approach with a boolean flag cannot achieve.
Therefore it is a better approach to use interruption to allow a task to be canceled. And you do not really need that cancel() method any more either :
#Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
// do work
}
}
As a bonus, any code that knows your thread, knows how to cancel it. Including standard ExecutorService implementations.
Care should be taken when catching an InterruptedException, since doing that clears the interrupted flag. It is adviseable to always restore the interrupted flag when catching the Exception, so clients also know it's time to stop doing what they're doing.
private BlockingQueue<Integer> queue;
#Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
try {
Integer id = queue.take(); // blocking method
// do work
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
To cancel a thread, you can simply keep a reference to the Thread object and call interrupt() on it :
Thread thread = new Thread(new InterruptibleTask());
thread.start();
// some time after :
thread.interrupt();
But a more elegant approach is keeping tabs on your task (and not so much the specific thread it runs on) through a Future object. You can do this by wrapping your Runnable or Callable in a FutureTask.
RunnableFuture<Void> task = new FutureTask<>(new InterruptibleTask(), null);
new Thread(task).start();
// some time after :
task.cancel(true); // true indicating interruption may be used to cancel.
A Future is key in controlling your task. It allows you to wait for its completion, and optionally receive a value the task calculated :
try {
String value = future.get(); // return value is generically typed String is just as example.
} catch (InterruptedException e) {
Thread.currentThread().interrupt(); // since future.get() blocks
} catch (ExecutionException e) {
logger.log(Level.SEVERE, "Exception on worker thread", e.getCause()); // the ExecutionException's cause is the Exception that occurred in the Task
}
If you have several tasks (or even just one) it is worth using an ExecutorService :
ExecutorService pool = Executors.newCachedThreadPool();
Future<?> submit = pool.submit(new InterruptibleTask());
pool.shutdownNow(); // depending on ExecutorService implementation this will cancel all tasks for you, the ones Executors returns do.
I have a processing loop of the form
while (true) {
doWork();
Thread.sleep(SLEEP_INTERVAL);
}
I want to make a Runnable out of this that can play well with ExecutorService and which will exit when ExecutorService.shutdownNow() is called.
I'm looking to write it this way:
public WorkerTask implements Runnable
{
#Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
doWork();
try {
Thread.sleep(SLEEP_INTERVAL);
}
catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
}
Simple testing shows it at least appearing to work in that the task gets interrupted and will exit and the ExecutorService will shut down, and appears to do so whether the interrupt arrives while doWork() is processing or during the sleep. (By varying how much work doWork() does and how big SLEEP_INTERVAL is I can pretty much control where the interrupt happens).
But when I google I see examples using Thread.interrupted() as well as Thread.currentThread().isInterrupted(). I understand that the former clears the interrupted flag while the latter leaves it, but is there any other difference I need to care about?
I also see versions where the result of Thread.currentThread().isInterrupted() or Thread.interrupted() is stored in a volatile variable and that variable is used as the while loop test condition. Is that just a style or is there a need to do that? In what I've written do I have to worry that somehow something can clear the interrupt flag between when it is set (whether by being received when the thread is live, or by my catching InterruptedException and reasserting the flag) and when Thread.currentThread().isInterrupted() is called in the loop test?
Your code looks fine to me. Introducing an additional volatile variable would be unnecessary complexity: the interrupt status does the job.
The recommended way, in Java Concurrency in Practice, to deal with interrupts in tasks is to either throw an InterruptedException (this is doable if the task is a Callable and not a Runnable), or to make sure the interrupt status is set and to exit from the task ASAP. Your code does that well.
Could you take a look at ScheduledExecutorService if it matches your requirements:
class BeeperControl {
private final ScheduledExecutorService scheduler =
Executors.newScheduledThreadPool(1);
public void beepForAnHour() {
final Runnable beeper = new Runnable() {
public void run() { System.out.println("beep"); }
};
final ScheduledFuture<?> beeperHandle =
scheduler.scheduleAtFixedRate(beeper, 10, 10, SECONDS);
scheduler.schedule(new Runnable() {
public void run() { beeperHandle.cancel(true); }
}, 60 * 60, SECONDS);
}
}}
Basically you should take advantage of java.util.concurrent libraries here .You should submit your task via ExecutorService.submit()and then call blocking methods like Future.get() , then you can be sure that those methods will respond to interruption as soon as possible by throwing an ExecutionException() .You probably should get rid of that Thread.sleep() since it is doing nothing . You want to sniff an interrupt as quickly as possible .You possibly also want to wait for a timeout in case your task is doing something inifinitely . So if the task terminates with a TimeOutException , the task is cancelled via its Future.
I call cancel() unconditionally since cancelling a completed task has no effect.
In that case you can do some thing like :
public static void main(String[] args) {
WorkerTask runnable;
TimeUnit unit;
Future<?> task = executor.submit(workerTask);
try{
task.get(timeout,unit);
} catch(TimeoutException e){
}catch(ExecutionException e){
throw e.getCause();
} finally{
//Harmless if the task already completed
task.cancel(true);
}
}
}