I'd like to check to see if a Thread is Interrupted, from some other Thread, without polling this to check - i.e. some kind of monitor.
Specifically, what I am trying to do is force-kill (Stop) a Thread when it is Interrupted. I will include a code example below of a trivial example of what I have done so far - it works, but polling to check if the Thread is interrupted is sub-optimal and I would like to avoid this.
public class ThreadTest
{
public static void main(final String[] args) throws InterruptedException
{
final Thread outerThread = new Thread()
{
#Override
public void run()
{
// Need to externally monitor the thread to detect and process interrupts (for cancellation)
final Thread thread = Thread.currentThread();
new Thread()
{
#Override
public void run()
{
while (true)
{
try
{
Thread.sleep(500);
}
catch (final InterruptedException e)
{}
if (thread.isInterrupted())
{
// Then kill it
thread.stop();
return;
}
}
}
}.start();
uninterruptibleForever();
}
};
outerThread.start();
// Ensure the thread has time to start up
Thread.sleep(500);
outerThread.interrupt();
// The thread should terminate at this point and not continue.
}
/** Some arbitrary task that runs forever and ignores interrupts */
public static void uninterruptibleForever()
{
while (true)
{
System.out.println(MessageFormat.format("I''m still running at {0}", new Date().toLocaleString()));
}
}
}
I can't recommend strongly enough that you don't use Thread#stop().
It should never have existed, was deprecated very quickly and frankly should have been removed about 20 years ago.
You have no idea what the thread is doing when you stop it and it is very easy to corrupt shared objects and leave external resources (e.g. files) in an invalid state.
Suppose the thread is in the middle of resizing a shared ArrayList<> there's risk the object will be corrupted and your whole program fails intermittently in ways you cannot fix.
Do not use Thread#stop() it is broken and cannot be fixed.
It's a terrible feature of Java that it leads people into invalid techniques regarding threads.
Caveat over - how about just overriding interrupt() in a sub-class?
public void interrupt(){
this.stop();
}
You've decided to sub-class Thread (rather than Runnable) so this will "work". "work" in the sense of what you're doing. Not actually work or anything.
The only valid way to solve this is have the thread you want to terminate co-operate by responding to interrupt() as an instruction to come to a suitable point and then terminate cleanly.
Or you can create another flag indicating the thread should end.
I don't know why you need to monitor the thread externally. But here is a small sample how you could do it if you really need it:
import java.util.LinkedList;
import java.util.List;
public abstract class MonitoredCallable implements Runnable {
private final List<InterruptedHandler> interruptedHandlers = new LinkedList<>();
protected abstract void runInternal() throws Exception;
#Override
public final void run() {
try {
runInternal();
} catch(Exception ex) {
}
for (InterruptedHandler interruptedHandler : interruptedHandlers) {
interruptedHandler.threadInterrupted(this);
}
}
public void addInterruptedHandler(InterruptedHandler interruptedHandler) {
this.interruptedHandlers.add(interruptedHandler);
}
public static interface InterruptedHandler {
void threadInterrupted(Thread t);
}
}
Now just use it like this:
MonitoredThread mt = new MonitoredThread() {
#Override
protected void runInternal() throws Exception {
//dosomething
}
};
mt.addInterruptedHandler(t->t.stop());
Related
I have following class:
public class PawnThread implements Runnable {
public void start() {
thread.start();
}
#Override
public void run() {
try {
while (... some finish condition ...) {
move();
synchronized (this) {
while (suspendFlag) {
wait();
}
}
}
} catch (InterruptedException e) {
System.err.println(pawn.toString() + ": thread interrupted :(");
}
}
void move() {
... some blocking actions
}
synchronized void suspend() {
suspendFlag = true;
}
synchronized void resume() {
suspendFlag = false;
notify();
}
}
Now I have a list of its objects:
private final List<PawnThread> pawnThreadList;
I defined some helper method to suspend all of them:
public void suspendAll() {
pawnThreadList.forEach(PawnThread::suspend);
}
Now suspend() method is only about changing flag. The requirement is, that when I leave suspendAll() method, all threads should be actually paused (they cannot be in RUNNABLE state) - for now it is not a case, beacause for some of them, it may take some time to actually finish their job before pause.
I would be grateful for advice what is correct design for this soulution.
Regards
Make PawnThread#suspend() wait for suspension to be completed:
public class PawnThread implements Runnable {
private final Waiter suspender = new Waiter();
private final Waiter suspending = new Waiter();
#Override
public void run() {
try {
while (...) {
suspending.suspend();
move();
suspending.resume();
suspender.await();
}
} catch (InterruptedException e) {
...
}
}
void suspend() throws InterruptedException {
suspender.suspend();
suspending.await();
}
void resume() {
suspender.resume();
}
}
public class Waiter {
private boolean waiting;
public synchronized void await() throws InterruptedException {
while (waiting) {
wait();
}
}
public synchronized void suspend() {
waiting = true;
}
public synchronized void resume() {
waiting = false;
notify();
}
}
The requirement is impossible to satisfy, but also makes no sense. In order for the thread to communicate the fact that it has suspended, the thread must be running. There is no way to ensure the thread has completed the suspension process.
But this is also not a sensible requirement. How can it possibly matter whether the thread has suspended itself or is about to suspend itself, so long as it has nothing left to do but suspend itself?
A sensible requirement should be satisfied by having each thread set some indication somewhere that it has received the suspend request and is about to stop executing. Then the calling thread can wait for all threads to have provided that indication.
Universal correct design for any parallel solution is to define streams of tokens and firing rule (see Petry Net tedminology). Most simple and useful firing rule is to start an action when all input tokens are ready. I your case, input tokens are hidden in whle condition and in suspend condition. Your mistake is you defined suspend condition as negative, while all tokens must be defined as positive. That is, a thread works where there are enough tokens, and stops when they are exhausted, and then thread waits while the number of tokens is increased by external threads.
Tokens may be of 2 kinds - black (pure permissions), passed by Semaphores, and color (messages), passed by BlockingQueues. These 2 communicator classes cover most of use cases. In some complex cases, user can create custom communicators using synchronized/wait/notify.
So canonical way to design any parallel program is as follows:
design Petry Net, with places for tokens (communicators), and transitions (actions).
map places to Semaphores/BlockingQueues/CustomCommunicators, and transition to threads (or Actors).
These are the 3 classes I have:
public class ChildThread extends Thread {
#Override
public void run() {
while (true) {
System.out.println("Child thread is running.");
if (Thread.currentThread().isInterrupted()) {
System.out.println("Child thread is interrupted.");
return;
}
}
}
}
public class MainThread extends Thread{
public Thread childThread = new ChildThread();
#Override
public void run() {
childThread.start();
}
}
public class App {
public static void main(String[] args) {
MainThread mainThread = new MainThread();
mainThread.start();
mainThread.childThread.interrupt();
}
}
When I run this, the child thread doesn't seem to be ever interrupted. It keeps printing: "Child thread is running."
However, if I put a debug breakpoint at mainThread.childThread.interrupt();, child thread will get interrupted.
And also, if I change App class like the following:
public class App {
public static void main(String[] args) throws Exception{
ChildThread childThread = new ChildThread();
childThread.start();
Thread.sleep(3000);
childThread.interrupt();
}
}
it works again. Child thread gets interrupted and stopped printing after 3 seconds.
It seems that the behaviors are different interrupting from a thread that directly started a child thread, and from a thread that didn't directly start a child thread. And it's also different depending on whether there's a breakpoint or not. It's so weird to me. How could this work in a complex system? I don't think a complex system can guarantee all interruption signals are from the original starters of threads.
Could anyone help explain this? I can't find anywhere that seem to have an answer.
You need the Thread.sleep before interrupting otherwise, you are interrupting before the child thread even before it has gotten a chance to start running. As per the API specs "Interrupting a thread that is not alive need not have any effect.". So, in affect, the interrupt statement is being ignored as at the time the thread is not active. Without the sleep, the thread become active AFTER the interrupt - hence is never interrupted.
public class App {
public static void main(String[] args) throws InterruptedException {
MainThread mainThread = new MainThread();
mainThread.start();
Thread.sleep(1); // <== This line is needed as otherwise, the next line will
// interrupt the thread, even before it has started running!
mainThread.childThread.interrupt();
}
}
What will happen if we access a thread which was stopped using stop() method.
UserThread t = new UserThread();
t.start();
System.out.println(t.getName());
System.out.println(t.getState());
t.stop();
System.out.println(t.getState());
Anyhow stop() method is deprecated in java8, but need the output for above. Is it possible to access the thread which was stopped means in terminated state?
Thanks in advance.
Why is Thread.stop deprecated?
Because it is inherently unsafe. Stopping a thread causes it to unlock
all the monitors that it has locked. (The monitors are unlocked as the
ThreadDeath exception propagates up the stack.) If any of the objects
previously protected by these monitors were in an inconsistent state,
other threads may now view these objects in an inconsistent state.
Such objects are said to be damaged. When threads operate on damaged
objects, arbitrary behavior can result. This behavior may be subtle
and difficult to detect, or it may be pronounced. Unlike other
unchecked exceptions, ThreadDeath kills threads silently; thus, the
user has no warning that his program may be corrupted. The corruption
can manifest itself at any time after the actual damage occurs, even
hours or days in the future.
What should I use instead of Thread.stop?
Most uses of stop should be replaced by code that simply modifies some
variable to indicate that the target thread should stop running. The
target thread should check this variable regularly, and return from
its run method in an orderly fashion if the variable indicates that it
is to stop running. To ensure prompt communication of the
stop-request, the variable must be volatile (or access to the variable
must be synchronized).
For example, suppose your applet contains the following start, stop and run methods:
private Thread blinker;
public void start() {
blinker = new Thread(this);
blinker.start();
}
public void stop() {
blinker.stop(); // UNSAFE!
}
public void run() {
while (true) {
try {
Thread.sleep(interval);
} catch (InterruptedException e){
}
repaint();
}
}
You can avoid the use of Thread.stop by replacing the applet's stop and run methods with:
private volatile Thread blinker;
public void stop() {
blinker = null;
}
public void run() {
Thread thisThread = Thread.currentThread();
while (blinker == thisThread) {
try {
Thread.sleep(interval);
} catch (InterruptedException e){
}
repaint();
}
}
If you are interested in seeing what is the state of a thread after you call stop you can suppress the deprecation warning by adding #SuppressWarnings("deprecation") before your test class definition.
For instance try the following code:
#SuppressWarnings("deprecation")
class test {
public static void main(String[] args) {
Thread t = new Thread() {
public void run() {
while(true) {
try {
Thread.sleep(1000);
}catch(Exception e) {}
}
}
};
t.start();
System.out.println(t.getName());
System.out.println(t.getState());
t.stop();
try {
Thread.sleep(1000); // wait for stop to take effect
}catch(Exception e) {}
System.out.println(t.getState());
}
}
Spoiler alert: the status is TERMINATED
Its advised not use stop() method in Thread class since this is deprecated.
If you want to abort the thread execution use interrupt()
class IntThread extends Thread{
public void run(){
try{
Thread.sleep(1000);
System.out.println("Didn't Interrupt me !!!");
}catch(InterruptedException e){
throw new RuntimeException("Thread interrupted..."+e);
}
}
public static void main(String args[]){
IntThread t1=new IntThread();
t1.start();
try{
t1.interrupt();
}catch(Exception e){System.out.println("Exception handled "+e);}
}
}
You can refer link for more details about interrupt.
I have been looking for ways to kill a thread and it appears this is the most popular approach
public class UsingFlagToShutdownThread extends Thread {
private boolean running = true;
public void run() {
while (running) {
System.out.print(".");
System.out.flush();
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {}
}
System.out.println("Shutting down thread");
}
public void shutdown() {
running = false;
}
public static void main(String[] args)
throws InterruptedException {
UsingFlagToShutdownThread t = new UsingFlagToShutdownThread();
t.start();
Thread.sleep(5000);
t.shutdown();
}
}
However, if in the while loop we spawn another another object which gets populated with data (say a gui that is running and updating) then how do we call back - especially considering this method might have been called several times so we have many threads with while (running) then changing the flag for one would change it for everyone?
thanks
One approach with these problems is to have a Monitor class which handles all the threads. It can start all necessary threads (possibly at different times/when necessary) and once you want to shutdown you can call a shutdown method there which interrupt all (or some) of the threads.
Also, actually calling a Threads interrupt() method is generally a nicer approach as then it will get out of blocking actions that throw InterruptedException (wait/sleep for example). Then it will set a flag that is already there in Threads (which can be checked with isInterrupted() or checked and cleared with interrupted(). For example the following code can replace your current code:
public class UsingFlagToShutdownThread extends Thread {
public void run() {
while (!isInterrupted()) {
System.out.print(".");
System.out.flush();
try {
Thread.sleep(1000);
} catch (InterruptedException ex) { interrupt(); }
}
System.out.println("Shutting down thread");
}
public static void main(String[] args)
throws InterruptedException {
UsingFlagToShutdownThread t = new UsingFlagToShutdownThread();
t.start();
Thread.sleep(5000);
t.interrupt();
}
}
i added a utlility class which essentially had a static map and methods.
the map was of type Long id, Thread thread. I added two methods one to add to the map and one to stop the thread via the use of interrupt. This method took the id as a parameter.
I also changed my loop logic from while true, too while ! isInterrupted. Is this approach ok or is this bad programming style/convention
thanks
How do we implement efficient exception handling when using threads.
I have a main program which creates 3 threads. How do we handle the exceptions for the exceptions thrown during the execution of thread?
Can we use the try/catch block or uncaughtexception. If so, can you please share some samples.
public class MyThreadTest {
public static void main(String[] args) {
Thread newThread = new Thread(new ThreadWithException());
// Add the handler to the thread object
newThread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler(){
#Override
public void uncaughtException(Thread t, Throwable e) {
System.out.println("ERROR! An exception occurred in " + t.getName() + ". Cause: " + e.getMessage());
}
});
newThread.start();
}
}
/**
* This thread throws a custom exception in its run method.
*/
class ThreadWithException implements Runnable {
#Override
public void run() {
throw new RuntimeException("Application Specific Exception!!");
}
}
Either you can use:
Thread#setUncaughtExceptionHandler to specify some code that is run when an exception is thrown (outside of normal program flow), or:
ExecutorService#invokeAll to run all of your blocks, and inspect the returned list for Future#get()'s throwing of ExecutionException. Another option is CompletionService, but this is slightly harder to use for such a simple case.
You can use try / catch block strategy:
Thread t = new Thread() {
#Override
public void run() {
try {
//..thread code
} catch (Exception e) {
}
}
};
It is easy to implement but in case of exception main thread of your application will never know what happened inside of child thread.
Better method would be to spawn threads using ExecutorService (as mentioned by FauxFaux). This will allow you to easily pass information about the error to main thread. Besides that, using ExecutorService allows you to write less code. You won't have to manage threads in your code but leave it for ExecutorService instead.
beacuse , recently, I have write a program with about 3 threads in order to fill a lot data from mysql and mongoDb to ElasticSearch. I share u my code.
I use java.util.concurrent.Executors.
First I have a main class. It calls
public void start() throws Exception {
this.logger.info("Main: Start the worker manually");
schedulerThreadPool = Executors.newScheduledThreadPool(this.maxNumberOfThread);
for (int i = 0; i < this.maxNumberOfThread; i++) {
Worker worker = new Worker();
long delay = i * this.sleepBetweenTaskStart;
schedulerThreadPool.scheduleAtFixedRate(worker, delay, this.minTimeBetweenEachTask, TimeUnit.MILLISECONDS);
}
}
And Worker implements Runnable and get Thread Id by below code.
this.threadId = Thread.currentThread().getId();
And just try catch in each Worker. Everything works normally.
#Override
public void run() {
try {
do...
} catch (Exception e) {
e.printStackTrace();
}
}