How do I stop a thread? - java

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();

Related

How to use java Thread.currentThread().interrupt()

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.

How to interrupt a thread with infinite loop and sleep in Java

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.

Why we use a flag to stop a thread?

When I tried to figure out how to stop a thread in a program with multiple threads,
I was suggested to call a method which actually sets a flag to tell that thread stop doing real works,like this:
public class ThreadTobeTerminated implements Runnable {
private static final Logger LOGGER = LoggerFactory.getLogger(IndexProcessor.class);
private volatile boolean running = true;
public void terminate() {
running = false;
}
#Override
public void run() {
while (running) {
try {
LOGGER.debug("Doing some real work ,like Counting...");
for(int i=0;i<100;i++){}
} catch (InterruptedException e) {
LOGGER.error("Exception", e);
running = false;
}
}
}
}
when I want to stop this tread ,I'll call threadInstance.terminate();.
Don't I need to literally stop this thread ?
Why I should leave this thread to do some useless work (method run called ,test the flag running==false then return)? I mean :this is a waste of time ,isn't it?
When the execution scope goes beyond the run() method, the thread stops, so the moment that the while loop is broken, the thread will stop.
This would also allow you to do some clean up if the situation requires it:
public void run() {
while (running) {
try {
LOGGER.debug("Doing some real work ,like Counting...");
for(int i=0;i<100;i++){}
} catch (InterruptedException e) {
LOGGER.error("Exception", e);
running = false;
}
}
//Clean up
}
The above approach allows you some control over how is the thread stops and what happens after as opposed to potentially just kill it, which could cause all kinds of problems.

sleeping in a thread without causing runOnUiThread to sleep

I have a thread in my android app, this thread has to sleep for a certain time in order to waiting some results which will be set by the runOnUiThread thread, the problem is when i tried to make the thread sleeps for a portion of time the runOnUiThread sleeps with it too and so it doesn't perform any processing till the other thread wakes up although runOnUiThread is exists in another separated thread.
that's my code:
The thread that contains the runOnUiThread :
Thread xbmc = new Thread (){
#Override
public void run(){
System.out.println("one");// working perfectly
runOnUiThread(new Runnable() {
public void run() {
try {
System.out.println("two");// not work till the other thread wakes up
} catch (Exception e) {
}
}
});
}
};
xbmc.start();
And this is the Thread that I make sleeps:
display = false;
Thread wait = new Thread(new Runnable() {
#Override
public void run() {
int d = 0;
while (d != 20) {
if (wake_up) {
display = true;
break;
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
d++;
}
if (!display) {
display = true;
}
}
});
wait.start();
while(!display){}// infinite loop waits for the thread to finish it's looks or something breaks it, and there is no something can break it but the `runOnUiThread` processing results
I think you're missunderstanding some basic concepts about Threads. Your threads, as you defined them, seem (moreless) ok, they are not blocking your UI as they're running in the background. What is blocking your UI is the while (!display) {} loop.
You're waiting here until your thread modifies that value, which I guess is not what you're trying to achieve. You'd need to define some other way of doing this, like for example, append the while (!display) content code block to the Thread.

How to stop a thread as soon as a certain amount of time expires? [duplicate]

This question already has answers here:
How to properly stop the Thread in Java?
(9 answers)
Closed 9 years ago.
I am having a problem trying to stop a thread instantly after a certain amount of time has elapsed, because thread.stop and similar others have been depreciated.
The thread that I am trying to stop uses my mouse and I need to stop it so that I can use my mouse in other ways.
What I was thinking is the code below, which was just to make another thread to watch how long the main thread has been running and if it is alive, stop it, but I can't accomplish this.
public void threadRun(int a) {
Thread mainThread = new Thread(new Runnable() {
#Override
public void run() {
// does things with mouse which may need to be ended while they
// are in action
}
});
Thread watchThread = new Thread(new Runnable() {
#Override
public void run() {
if (timeFromMark(mark) > a) {
if (mainThread.isAlive()) {
// How can I stop the mainThread?
}
}
}
});
}
You need to define a class for your second thread that extends runnable and pass the first thread as an argument.
Then you can stop the first thread.
But instead of doing this manually, have a look at the Java ThreadPoolExecuter and its awaitTermination(long timeout, TimeUnit unit) method. (http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ThreadPoolExecutor.html )
Will save a lot of work.
ExecutorService executor = Executors.newFixedThreadPool(1);
Runnable r = new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
try {
System.out.println("doing stuff");
Thread.sleep(10000);
System.out.println("finished");
} catch (InterruptedException e) {
System.out.println("Interrupted before finished!");
}
}
};
executor.execute(r);
executor.shutdown();
try {
executor.awaitTermination(1, TimeUnit.SECONDS);
executor.shutdownNow();
} catch (InterruptedException e) {
//
}
System.out.println("Thread worker forced down. Continue with Application...");
Produces:
doing stuff
Interrupted before finished!
Thread worker forced down. Continue with Application...
Last two messages are nearly equal in terms of time and may change positions (its two different threads, continuing)
Java has deprecated methods for explicitly killing another thread (like Thread.stop / Thread.destroy). The right way is to make sure the operations on the other thread can handle being told to stop (for example, they expect an InterruptedException, which means you can call Thread.interrupt() in order to stop it).
Taken from How do I kill a thread from another thread in Java?
Killing/stopping threads is a bad idea. That's why they deprecated those methods. It's better to ask the thread to stop. E.g., something like the example below. (But note: if "do_something()" takes a long time, then you might want to use an interrupt to abort whatever it is.)
import java.util.concurrent.atomic.AtomicBoolean;
public class Stoppable {
private AtomicBoolean timeToDie = new AtomicBoolean(false);
private Thread thread;
public void start() {
if (thread != null) {
throw new IllegalStateException("already running");
}
thread = new Thread(new Runnable() {
public void run() {
while (!timeToDie.get()) {
// do_something();
}
}
});
thread.start();
}
public void stop() throws InterruptedException {
timeToDie.set(true);
thread.join();
thread = null;
}
}

Categories