if I override my run function as ,
Thread t = new Thread(){
public void run(){
try {
if(Thread.currentThread().isInterrupted()) {
doSomePrcocess() // is the isInerrupted() flag seeting to true?
return; //Terminates the current Thread
}
//otherwise
runScript();
} catch (Exception e) {
e.printStackTrace();
}
}
};
t.start();
and then If I call, Thread.currentThread().interrupt() from any point in the code, should the thread halt there and start running doSomeProcess() at that point? if yes, then how the interrupted flag gets to set true? If no, how to do this?
If thread is in sleeping or waiting state calling the interrupt() method on the thread, breaks out the sleeping or waiting state
throwing InterruptedException
If the thread is not in the sleeping or waiting state, calling the
interrupt() method performs normal behaviour and doesn't interrupt the thread but sets the interrupt flag to true.
Thread class has provision to deal with thread interruption as
public void interrupt()
public static boolean interrupted()
public boolean isInterrupted()
If you intend to go with the only once execution of doSomePrcocess then you have to go with which will check and clear the Thread interruption state for successive calls.
public static boolean interrupted()
Using below will only check the status and no modification.
public boolean isInterrupted()
I have got a running example with comments in your code below. Try running it a few times to see if it clarifies your concept.
Normally you would interrupt a thread from another thread and yes doSomeProcess will get invoked in the next cycle of the loop which could be 1 ms after the thread was interrupted or 1 hour after depending on the logic implemented in your methods.
public class InterruptTest {
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread() {
public void run() {
while (true) {
try {
if (Thread.currentThread().isInterrupted()) {
doSomePrcocess(); // is the isInerrupted() flag seeting to true? - Yes
return; // Terminates the current Thread - yes
}
// otherwise
runScript();
} catch (Exception e) {
e.printStackTrace();
}
}
}
private void runScript() {
System.out.println("runScript interrupted status:" + this.isInterrupted());
sleepy(100);
}
private void doSomePrcocess() {
System.out.println("doSomePrcocess interrupted status:" + this.isInterrupted());
sleepy(500);
}
private void sleepy(int millis) {
try {
Thread.sleep(millis);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Thread.currentThread().interrupt(); // try commenting this out to see what happens.
}
}
};
t.start();
Thread.sleep(1000);
t.interrupt(); // generally you would call interrupt on another thread.
}
}
No, it doesn't work like that. The isInterrupted method checks if the flag is set, it does not declare a handler. There is no way to define a central handler that will automatically be called when a thread is interrupted. What you can do is to catch InterruptedException and call the handler, plus check the interrupt flag regularly to see if it is time to stop.
Related
I was trying out the below code, I interrupted a user thread, when I print the value of isInterrupted it is returning false, I didn't got a single true value, over here the flag will get reset when the exception has been caught or on calling interrupted method.
Secondly, as per my understanding sleep method should throw and interruptedException in each iteration, the value in catch print, but it is throwing only once.
class ThreadInterruptt extends Thread
{
public void run()
{
for(int i = 0; i<100;i++)
{
try {
Thread.sleep(1000);
System.out.println(i);
System.out.println(isInterrupted());
} catch (InterruptedException e) {
System.out.println("Thread Interrupted");
}
}
}
}
public class ThreadInterrupt {
public static void main(String ag[]) throws InterruptedException
{
ThreadInterruptt t = new ThreadInterruptt();
t.start();
Thread.sleep(100);
t.interrupt();
}
}
You wouldn't ever get to the isInterrupted() check if you are interrupted: Thread.sleep() would have thrown an exception, and also it clears the interrupted status of the Thread, as described in the Javadoc.
And you're then discarding the fact the thread was interrupted (because you don't reset the interrupted flag on catching the exception), so it's not interrupted on the next iteration.
I want to start a thread, interrupt it and start a new thread. The Problem is, that this doesn't really work. The first thread starts and gets interrupted, but the following thread gets interrupted before it even can start. So interrupt() interrupts the old and the new thread. The output looks like this:
run()-method starts
Thread Counter:0
Thread Counter:1
Thread Counter:2
Thread Counter:3
Thread Counter:4
Thread Counter:5
Thread Counter:6
8 seconds are over
Thread is not null
Thread will be interrupted now
catch
run()-method starts
catch
8 seconds are over
Thread is not null
Thread will be interrupted now
....
You can see that the thread starts the first time. Then the thread gets interrupted and 'catch' is called. So far, so good. After this, the next thread is going to start, but this time the thread gets interrupted immediately and 'catch' is called right after 'run()-method starts'.
So, I can't figure out why this is happening. I don't want two threads being interrupted in quick succession.
Here is my code:
public class MyRunnable {
static Thread myThread;
static boolean stop;
static Runnable myRunny = new Runnable() {
#Override
public void run() {
System.out.println("run()-method starts");
try {
int j = 0;
while (!stop) {
Thread.sleep(1000);
System.out.println("Thread Counter:"+j);
j++;
}
} catch (InterruptedException e) {
System.out.println("catch");
myThread.interrupt();
}
};
};
public static void main(String[] args){
myThread = null;
while(true) {
stop = false;
if(myThread != null) {
System.out.println("Thread is not null ");
System.out.println("Thread will be interrupted now");
myThread.interrupt();
}
myThread = new Thread(myRunny);
myThread.start();
try {
Thread.sleep(8000);
System.out.print("8 seconds are over "+ "\n");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
catch (InterruptedException e) {
System.out.println("catch");
myThread.interrupt();
}
myThread field is replaced with new reference before calling myThread.interrupt(), so you interrupt the new thread!
So interrupt() interrupts the old and the new thread.
Your diagnosis is incorrect. A call to Thread.interrupt will interrupt one thread once.
What your example is doing is interrupting one thread, and that thread is catching InterruptedException and interrupting a second thread in the exception handler. Two calls to interrupt are being made in quick succession on different threads.
I don't want two threads being interrupted in quick succession.
Well change
} catch (InterruptedException e) {
System.out.println("catch");
myThread.interrupt();
}
to
} catch (InterruptedException e) {
System.out.println("catch");
}
I am starting a new thread in my app's onCreate() method like so:
stepsLogger = new Runnable() {
while(!Thread.currentThread().isInterrupted()){
//my code
try {
Thread.currentThread().sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
loggerThread = new Thread(stepsLogger);
loggerThread.start();
While it is not interrupted, it is supposed to do its thing every 10 seconds.
I am logging some text at the start of the Runnable to see how often the code gets run. The first time I run the app it's fine, but every time i restart, the text gets logged more frequently which means that more threads are running.
I have tried to stop them in the onDestroy() method:
#Override
protected void onDestroy() {
super.onDestroy();
loggerThread.interrupt();
loggerThread = null;
}
How do I make sure that the old thread gets stopped whenever the app is restarted?
Thread.interrupt() will wake up a sleeping thread with an InterruptedException, so you're most of the way there already. I'd change your loop in the following way:
while (true) {
// some code
try {
Thread.currentThread().sleep(10000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt(); // restore the thread's interrupted flag
break;
}
}
The bit about re-interrupting the thread is subtle. You can read more about it in this post from one of the primary JVM architects: https://www.ibm.com/developerworks/library/j-jtp05236/
In case this link ever dies, the gist of it is that there can be multiple "recipients" of thread interruption. Catching the exception implicitly clears the thread's interrupted flag, so it's useful to set it again.
You could use a volatile boolean variable to determine when to stop. Something like this:
class WorkerRunnable implements Runnable {
private volatile boolean shouldKeepRunning = true;
public void terminate() {
shouldKeepRunning = false;
}
#Override
public void run() {
while (shouldKeepRunning) {
// Do your stuff
}
}
}
To start it:
WorkerRunnable runnable = new WorkerRunnable();
new Thread(runnable).start();
To stop it:
runnable.terminate();
I have written the following code where the start method is supposed to wait until the stop method notifies it. But during the execution the log line below the start method gets printed though I have specified it to wait. Below shown is my start method implementation is as follows.
private static boolean stopThread = false;
public static void start(String[] args) {
startThread();
synchronized (serviceThread) {
try {
while(stopThread) {
serviceThread.wait();
}
LOGGER.log(Level.INFO, "Thread: Just after wait method");
} catch (InterruptedException e) {
LOGGER.log(Level.INFO, "'Wait' interrupted: " + e.getMessage());
}
}
}
Below shown is my stop method implementation.
public static void stop(String[] args) {
if (serviceThread != null) {
LOGGER.log(Level.INFO, "Stopping the thread");
serviceThread.interrupt();
LOGGER.log(Level.INFO, "Thread: Successfully interrupted");
synchronized (serviceThread) {
LOGGER.log(Level.INFO, "About to notify");
serviceThread.notify();
stopThread = true;
}
stopPlugins();
kubeLogManager.closeLogger();
messageBus.terminateMessageBus();
System.exit(0);
} else {
LOGGER.log(Level.INFO, "No thread to interrupt");
}
}
Why does that log line below the wait method get printed even before the stop method has been called? Please advice.
See the documentation for Object.wait:
https://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#wait()
interrupts and spurious wakeups are possible, and this method should always be used in a loop:
synchronized (obj) {
while (<condition does not hold>)
obj.wait();
... // Perform action appropriate to condition
}
You should use a variable to indicate when stop() has been called, and set it before you call notify(). Also, it's safer to use notifyAll(), since it still works if you somehow get another thread waiting on the object.
i've been fighting with this over few hours now. Here's the code:
#Override
public void run()
{
try
{
wscript.setBid(0.30);
wscript.setServiceMode(WebScript.ServiceMode.ON);
for(;!Thread.currentThread().isInterrupted();)
{
Positioning(demandedPosition, maximumBid);
if(Thread.currentThread().isInterrupted())
break;
Thread.sleep(10000);
}
wscript.setServiceMode(ServiceMode.OFF);
Log("Algorithm has been canceled!");
}
catch (InterruptedException e)
{
wscript.setServiceMode(ServiceMode.OFF);
Log("Algorithm has been canceled!");
return;
}
The thing is, that i would like to interrupt it in legit way with this code:
private void StopService()
{
service.interrupt();
}
When I call this method when Thread.sleep() is running, it gets InterruptedException and everything works fine. However, as I call it when the PositioningAlgorithm is running nothing is happenning, the thread acts like it never got the interruption state.
Regards,
DualCore
EDIT: It is essential for me that the call Log("Algorithm has been canceled!"); will be executed after interruption.
SOLVED: I had overwritten Thread.interrupt() to edit class local variable which was checked whether the thread is ready to end:
service = new Thread(mechanism)
{
#Override
public void interrupt()
{
super.interrupt();
mechanism.ReadyToReturn = true;
}
};
And here's updated thread main algorithm:
#Override
public void run()
{
try
{
wscript.setBid(0.30);
wscript.setServiceMode(WebScript.ServiceMode.ON);
for(;!ReadyToReturn || !Thread.currentThread().isInterrupted();)
{
Positioning(demandedPosition, maximumBid);
if(ReadyToReturn || Thread.currentThread().isInterrupted())
break;
Thread.sleep(10000);
}
wscript.setServiceMode(ServiceMode.OFF);
Log("Algorithm has been canceled!");
}
catch (InterruptedException e)
{
wscript.setServiceMode(ServiceMode.OFF);
Log("Algorithm has been canceled!");
return;
}
}
The reason why this might be happening is that Positioning clears isInterrupted flag (see https://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#interrupted%28%29) and/or catches somewhere InterruptedException (or Exception/Throwable).
One possibility is to use another flag (e.g. using volatile variable/ AtomicBoolean/ThreadLocal) to indicate whether the thread should be interrupted.