We all know that when catching an interruptedexception we are supposed to
Thread.currentThread().interrupt();
However, from my tests, that flag is already set.
Thread t = new Thread(() -> {
try {
Thread.sleep(1000L);
} catch (InterruptedException e) {
// Thread.currentThread().interrupt();
}
});
t.start();
System.out.println(t.isInterrupted());
t.interrupt();
System.out.println(t.isInterrupted());
Prints:
false
true
So what is the point of that commented out line?
If the line is commented out and you try to check in the thread itself if it is interrupted, you will get false as response.
Thread t = new Thread(() -> {
try {
Thread.sleep(1000L);
} catch (InterruptedException e) {
// Thread.currentThread().interrupt();
}
System.out.println(Thread.currentThread().isInterrupted());//false
});
If you execute the line you get true.
Thread t = new Thread(() -> {
try {
Thread.sleep(1000L);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
System.out.println(Thread.currentThread().isInterrupted());//true
});
Edit:
The use of interrupt() is to inform the thread that it should be terminated. It replaces the stop() method which immediately terminates a thread at the currently executed line. Since stopping leaves files or streams open, this way is deprecated. The interrupt should be used to safely close all open streams and then safely terminate the thread. If the thread does not have the ability to create ghosts (leave streams/files open), the handling can be omitted. However, it should always be remembered that the interrupt() method does not terminate the thread, instead it continues to execute the code after the exception as if nothing had happened.
Related
I have created ExecutorService and submitted a job. The job might be time-consuming. So I have given timeout as 2 seconds. If the execution takes more than 2 seconds, I want to kill that thread.
public void threadTest() {
ExecutorService executor = Executors.newSingleThreadExecutor();
try {
executor.submit(() -> {
try {
String threadName = Thread.currentThread().getName();
Thread.sleep(7000);
System.out.println("process completed after 7 seconds");
} catch (Exception e) {
e.printStackTrace();
}
}).get(2, TimeUnit.SECONDS);
}catch (Exception e){
}
executor.shutdown();
}
public static void main(String[] args) throws Exception {
System.out.println("main start");
ThreadBreaker tb = new ThreadBreaker();
tb.threadTest();
System.out.println("main end");
}
output
main start
main end
process completed after 7 seconds
The function threadTest exited after 2 seconds as I expected. But the submitted job kept running. I want to stop the submitted task if it couldn't complete in a given timeout.
Once you have submitted a task to executorService you've got an Future object. And you can cancel execution by Future.cancel(true) call.
Keep in mind that canceling the active running task is possible when you have accurate InterruptException handling inside a task.
In the example above:
Thread.sleep(7000);
will raise an interrupted exception and you should not catch it (or if you catched it re-raise another exception)
When you use ExecutorService you cannot kill Threads by yourself. ThreadPool decides when to kill a Thread (typically it might happen if the Thread was interrupted).
In your case you should catch the TimeoutException and cancel the Future. If your "real" task is responsive to interruption(invoking and handling InterruptedException correctly) it will work. Otherwise you should check the Thread.currentThread().isInterrupted() status in a loop.
Your example code will look like :
public void threadTest() {
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<?> submit = executor.submit(() -> {
try {
String threadName = Thread.currentThread().getName();
Thread.sleep(7000);
System.out.println("process completed after 7 seconds");
} catch (InterruptedException e) {
Thread.currentThread().interrupt(); //preserve interruption status. based on this ThreadPool's interruption Policy will decide what to do with the Thread
}
});
try {
submit.get(2, TimeUnit.SECONDS);
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace(); //handle this
} catch (TimeoutException e) {
submit.cancel(true); //cancel the task
}
executor.shutdown();
}
Also remember that if you execute a task in a ThreadPool and you execute operations that might from InterruptedException in most cases you should preserve the interruption status.
In the below code snipped when dispose() is called, then the emitter thread is interrupted (InterruptedException is thrown out of sleep method).
Observable<Integer> obs = Observable.create(emitter -> {
for (int i = 0; i < 10; i++) {
if (emitter.isDisposed()) {
System.out.println("> exiting.");
emitter.onComplete();
return;
}
emitter.onNext(i);
System.out.println("> calculation = " + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
emitter.onComplete();
});
Disposable disposable = obs
.subscribeOn(Schedulers.computation())
.subscribe(System.out::println);
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
disposable.dispose();
From debugging session I see that the interrupt origins from FutureTask which is cancelled during disposal. In there, the thread that is calling dispose() is checked against runner thread, and if it does not match, the emitter is interrupted. The thread is different since I used computation Scheduler.
Is there any way to make dispose not interrupt such emitter or is it how this actually should always be handled? An issue I see with this approach is when I would have an interruptible operation (simulated here by sleep) that I would want to complete normally before calling onComplete().
Please refer to What's different in 2.0 - Error handling.
One important design requirement for 2.x is that no Throwable errors should be swallowed. This means errors that can't be emitted because the downstream's lifecycle already reached its terminal state or the downstream cancelled a sequence which was about to emit an error.
So you can either wrap everything inside a try/catch and properly emit the error:
Observable<Integer> obs = Observable.create(emitter -> {
try {
// ...
} catch (InterruptedException ex) {
// check if the interrupt is due to cancellation
// if so, no need to signal the InterruptedException
if (!disposable.isDisposed()) {
observer.onError(ex);
}
}
});
or setup a global error consumer to ignore it:
RxJavaPlugins.setErrorHandler(e -> {
// ..
if (e instanceof InterruptedException) {
// fine, some blocking code was interrupted by a dispose call
return;
}
// ...
Log.warning("Undeliverable exception received, not sure what to do", e);
});
I am using a Java based file conversion tool which converts PDF to DOCX, but sometimes while conversion it stuck, if input file size is more then 1 MB and start utilizing 100% CPU and more memory and keep running. I want to stop this continuous thread.
I know stop() function is deprecated.
Calling thread.interrupt(); is not helping, since thread is keep running.
There is no loop in the code ...so cannot check for interrupted flag in loop
How to Stop a running Thread t.
public class ThreadDemo implements Runnable {
Thread t;
PdfToDocConversion objPdfToDocConversion;
ThreadDemo() throws InterruptedException {
t = new Thread(this);
System.out.println("Executing " + t.getName());
// this will call run() fucntion
t.start();
Thread.sleep(2000);
// interrupt the threads
if (!t.interrupted()) {
System.out.println("Interrupted");
t.interrupt();
}
System.out.println(t.isInterrupted()); // true
System.out.println(t.getName());
System.out.println(t.isAlive()); /// still true
// block until other threads finish
try {
t.join();
} catch (InterruptedException e) {
}
}
public void run() {
objPdfToDocConversion = new PdfToDocConversion();
try {
objPdfToDocConversion.convertDocToPdf();//inside this function thread got stuck
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
System.out.print(t.getName() + " interrupted:");
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String args[]) {
try {
new ThreadDemo();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
You can build your own logic in killing the thread by the help of boolean flag.
public class RunningThread implements Thread {
private volatile boolean running = true;
public void run() {
while (running) {
try {
// Add your code here
} catch (InterruptedException e) {
if(!running){
break;
}
}
}
}
public void stopThread() {
running = false;
interrupt();
}
}
Here is the usecase:
RunningThread thread = new RunningThread();
thread.start(); // start the thread
thread.stopThread(); // stops the thread
The approach above is originally used by Google developers in on of there framework a.k.a Volley library.
Thread.interrupt() only sets a flag within the Thread object that the Thread should be interrupted. It does not cause the target Thread to throw an InterruptedException, instead code that can be interrupted must continually check that flag to see if someone has requested it be interrupted. That code then must handle it, usually by throwing an InterruptedException.
Some of the answers say about stopping the loop with volatile boolean isRunning but I do not see any loop in your example. Interrupting the thread does not actually interrupt it "right now". It just says "thread will be interrupted as soon as there will be such an opportunity". In your case I would suggest to close your PDF file and flag it with some boolean - then you can catch the IOException and if the flag is set - it means that you caused this situation and you can finish the thread.
I tried to use multiple threads, sadly no luck:
public synchronized boolean pingServer(final String ip, final short port) {
final boolean[] returnbol = new boolean[1];
Thread tt = new Thread(new Runnable() {
#Override
public void run() {
try {
Socket s = new Socket(ip, port);
s.close();
returnbol[0] = true;
} catch (IOException e) {
returnbol[0] = false;
}
}
});
tt.start();
try {
tt.join();
} catch (InterruptedException e) {
tt.stop();
}
tt.stop();
return returnbol[0];
}
The main thread still Freezes for some reason.
Is there a "lagless" way to ping a server?
What exactly did you want to got in
try {
tt.join();
} catch (InterruptedException e) {
tt.stop();
}
block?
Here you joined to parallel thread and waits till this thread will ends (got ping result).
You have next options:
Wait till ping ends
Don't wait... and don't got result
Use some concurrency classes like Future<> to got result (but you will block thread at moment you ask result if it not retrieved yet)
Or you can use some 'callback' function/interface to threw result from inner 'ping' thread.
You will need to remove the following lines from your code.
The tt.join() will force the main thread to wait for tt to finish.
try {
tt.join();
} catch (InterruptedException e) {
tt.stop();
}
tt.stop();
Use a Future instead to get the result for later use
I have two threads, threadOne waits for user input, threadTwo interrupts it with an interrupt() method before user input is received .
I would like to execute a block of code upon successful interruption of threadOne. I tried doing that by catching a ClosedByInterruptException within threadOne's run() method, but the compiler gives the following error:
exception ClosedByInterruptException has already been caught.
Here's the code:
class InputInterruption {
public static void main(String[] args) {
final Thread t2 = new Thread() {
public void run() {
try {
System.out.print("make a selection: ");
String userInput = (new BufferedReader(new InputStreamReader(System.in))).readLine();
System.out.println(String.format("user input: %s", userInput));
} catch (IOException e) {
System.out.println("Oops..somethign went wrong.");
System.exit(1);
} catch(ClosedByInterruptException e) {
System.out.println("Successfully interrupted");
}
}
};
t2.start();
Thread t1 = new Thread() {
public void run() {
try {
sleep(1000);
System.out.println("interrupting InputStreamReader");
t2.interrupt();
System.exit(0);
} catch (InterruptedException e) {
System.out.println("Successfully interrupted");
}
}
};
t1.start();
}
}
ClosedByInterruptionException extends IOException. Try switching the order of your catch statements.
ClosedByInterruptException is a subclass of IOException so your first catch block intercepts all IOException instances including ClosedByInterruptException.
Change the order of catch blocks and you are good.
To wait for a thread to complete, you could use Thread.join(). Change your t1 code to the following:
....
t2.interrupt();
t2.join();
....
Disclaimer: I haven't tried this code myself.
ClosedByInterruptException is actually sub class of IOException. So even if the try block throws ClosedByInterruptException it will be caught by the first catch block with statement:
catch (IOException e). Change the order and you should be good to go.
I tried doing that by catching a ClosedByInterruptException within threadOne's run() method...
Other's have solved the exception compilation error but I do not see any methods that actually throw ClosedByInterruptException so I'm surprised your code compiles. Your code does not compile for me in Eclipse for that reason. Maybe your IDE is not making the unthrown exception an error -- I'd recommend turning on that error/warning. ClosedByInterruptException is only thrown by certain NIO channels that implement InterruptibleChannel.
If you are reading from a normal stream, the only way to stop the thread from reading is to close the underlying stream. In this case you could try to close System.in but that may not actually stop the thread from reading unfortunately. On OS X, closing System.in causes the readLine() method to return null in the reader thread. You then can continue and execute some sort of code block as necessary.
sleep(1000);
System.out.println("closing InputStreamReader");
System.in.close();
Then you can do:
String userInput =
new BufferedReader(new InputStreamReader(System.in)).readLine();
if (userInput == null) {
// stream was closed, do something special
...
Btw, in the interrupting code you have:
try {
sleep(1000);
t2.interrupt();
} catch (InterruptedException e) {
System.out.println("Successfully interrupted");
}
The output message there is misleading. If sleep(...) throws a InterruptedException then it was the thread that was sleeping that was interrupted. It has nothing to do with the t2.interrupt() call. Just FYI.