How to use volatile boolean to check whether the thread should run? - java

I have a class that extends threads as seen below, and I want it to have a volatile boolean field that it checks to decide whether to continue running or not. The shouldRun() method is called from the EDT of my GUI.
How do I get this thread to check the boolean to know whether it should run or wait() from my GUI's Event Dispatcher Thread?
public class RobotThread extends Thread{
public volatile boolean run;
//if running == true, let thread run
//if running == false, invoke wait() somehow;
public RobotThread(AutoClicker autoClicker) {
super(autoClicker);
run = true;
}
public void setRun(boolean shouldRun) {
this.run = shouldRun;
}
public boolean getRun() {
return run;
}
}
In general, I just want to be able to get this thread to wait() and restart from the Event Dispatcher Thread of my GUI with button. If there are any better ways to do this I'll be happy to hear it too.

For the waiting and restarting I believe an infinit loop, wait and notify methods are what you're looking for. For instance, look at this guide.

Related

Can I synchronize reads of control variables?

The following code will work, but I slightly resent having to write the isRunning() method:
class Test {
private boolean running;
public void startX() {
synchronized(this) {
running = true
}
while (isRunning()) {
//do something
}
}
public synchronized void stopX() {
running = false;
}
private synchronized boolean isRunning() {
return running;
}
}
Can I synchronize reads of the running variable in the while (running){} in some other way, or do I have to write the isRunning() method? The same question applies to other control variables as well, eg
for (;running;) {}
or
if (running) {}
In all of these cases it seems as though you're forced into writing a pointless method to get the synchronization correct. Am I missing something?
if you are only resetting the value of running once to designate to stop, you might be able to use the volatile keyword.
However, if you need to start and stop many times, this won't work. This is because volatile fields "may miss an update"
Here's a link to explanation of when volatile works in cases like this link
here's the code sample from that link incase it goes dead:
public class StoppableTask extends Thread {
private volatile boolean pleaseStop;
public void run() {
while (!pleaseStop) {
// do some stuff...
}
}
public void tellMeToStop() {
pleaseStop = true;
}
}
If you need to start and stop many times, then you need to either use one of the Java 5 concurrent lock objects or explicit synchronization
You could make the running field volatile. Making the field volatile puts the JVM on notice that it should make changes to that field visible to other threads.
The "miss an update" caveat is for cases where you want to read a value and update based on that value, which doesn't seem applicable here.
Multiple threads can write to this field, if all they're doing is setting a boolean flag then this won't be a problem.
Alternatively, if you are trying to cancel a thread, there's already an equivalent flag provided on Thread for this (and the visibility issue is taken care of). You can call interrupt on a thread, the code in the Runnable can query Thread.currentThread().isInterrupted() in order to tell whether it's been interrupted. This is preferable over using your own flag because the interruption will cause the thread to wake up if it is waiting or sleeping. With your own flag you have to wait until control reaches a place where the flag can be tested.
just to add up to other people's answer that suggested volatile .
Alternatively you could create a class for the checks.
I have made the variable to be static, so all threads will be pointing to same object.
class Runner{
boolean static running=true;
public static synchronized boolean getRunning(){
return running;
}
public static synchronized boolean setRunning(boolean r){
running=r;
}
}
NOTE:
if you don't require the global variable, then remove the static

Why can Boolean flag not also be used as wait() / notifyAll() mutex?

I have a long-running Runnable. It performs a large number of iterations inside a while-loop in its run() function. I need functionality to pause and resume the runnable, which I implemented using a volatile Boolean pauseFlag that can be set by another thread.
Once the Runnable has detected that pauseFlag is true, it calls pauseFlag.wait() to pause its execution. Resuming is done through setting pauseFlag to false and then calling pauseFlag.notifyAll().
So the pauseFlag both acts as a flag and a mutex. This combined functionality does not work, however. The Runnable keeps blocking on pauseFlag.wait() indefinitely.
If I create a separate mutex, say, Object mutex = new Object(); and use mutex.notifyAll() / mutex.wait(), while still using pauseFlag as a boolean flag, the Runnable does behave as intended.
The non-working code is shown below:
public class PausableRunnable implements Runnable
{
private boolean done;
private volatile Boolean pauseFlag = false;
/** Pause execution. This is an asynchronous (non-blocking) call. */
public void pause() // <-- called by another thread
{
pauseFlag = true;
}
/** Resume execution */
public void resume() // <-- called by another thread
{
pauseFlag = false;
synchronized (pauseFlag)
{
pauseFlag.notifyAll();
}
}
#Override
public void run()
{
try
{
while (!done && !Thread.currentThread().isInterrupted())
{
while (pauseFlag)
{
synchronized (pauseFlag)
{
// Pause flag was set. Suspend until we are notified that we can continue
pauseFlag.wait();
}
}
// execute our main behaviour. set done = true when done iterating.
// ....
}
} catch (InterruptedException e)
{
Thread.currentThread().interrupt();
}
}
}
So, while I have found a solution by using a separate object, I'd like to understand the issue. Why doesn't the above implementation work?
I made this very same mistake once.
wait/notify works on an object, not a reference
When you change the object referred to by
private volatile Boolean pauseFlag
the wait is still referring to the original object. (As pointed out in the comments, there will usually be only two Boolean objects, TRUE and FALSE, making this even harder to debug, because you might get the correct one by chance)
So it's best to use a final reference that never changes its underlying object when using wait/notify.

Java thread won't join

Okay I'm sure I'm missing something simple here but can't see it. I'm using a flag to end a thread and then joining it to clean up neatly, but the join never finishes it just gets stuck waiting. There is currently nothing in the thread's run loop so it isn't getting stuck in a separate loop.
Thread:
package com.nox.willywars;
public class GameThread extends Thread {
//{{Variables
private boolean running;
//}}
//{{Getters/Setters
public void setRunning(boolean running) {
this.running = running;
}
//}}
//{{Constructor
public GameThread() {
running = false;
}
//}}Constructor
//{{Public methods
#Override
public void run() {
while(running) {
///...CODE GO HERE
}
}
public boolean isRunning() {
return running;
}
//}}
}
Code that fails to stop it:
//{{Lifecycle methods
#Override
public void create() {
//LOAD! Probably debug temp
TileFactory.load();
mapScreen = new MapScreen();
setScreen(mapScreen);
gameThread = new GameThread();
gameThread.setRunning(true);
gameThread.start();
}
#Override
public void resize(int width, int height) {
}
#Override
public void pause() {
killGameThread();
}
private void killGameThread() {
if(gameThread != null) {
if(gameThread.isAlive() && gameThread.isRunning()) {
gameThread.setRunning(false);
boolean retry = true;
while(retry) {
try {
gameThread.interrupt();
gameThread.join();
retry = false;
} catch (InterruptedException e) {}
}
}
gameThread = null;
}
}
//}}
Currently it reaches gameThread.join() and gets stuck there, waiting for the thread to finish. Am I missing something here? As I understand the thread should finish once running is set to false and then joining should happen normally because it's already stopped.
Edit: Added some more code from the class that runs GameThread. Pause() is where KillGameThread is executed. I've made running volatile but it's had no effect.
I found another weird symptom too: Some people suggested looking at what's inside GameThread when it's stuck, so I went into the debugger. While join() is stuck I suspended the GameThread thread and saw it was on while(running), and running was definitely false. Then when I stepped over the code it exited the loop and finished correctly, seemingly caused by my debugging. It's as if the thread is somehow suspended?
first set the running flag as volatile
private volatile boolean running;
What does game thread do exactly, maybe it has blocked by some I/O operation.
and if the game thread doesn't sleep/wait/join, so interrupting it is useless.
you need to share the game thread code.
As user2511414 pointed out, try with using volatile. In short, this will make sure the value od running is always accessed directly and not cached.
It setting volatile won't solve the situation, he problem most probably lays in the code section of a GameThread#run method that you commented out.
You can try using jstack or jvisualvm to get a Thread Dump of the thread you're trying to join.
This will at least show you where is it hanging, and may lead you to a solution.
The running flag is not properly synchronised. This could (in theory) result in the thread not noticing the state change ... due to the way that the Java memory model works. You should either declare it as volatile or always access and update it in synchronized method calls (or synchronized blocks).
But (IMO) the real problem is in the way (actually the ways) that you are telling the thread to stop, and haw the thread is checking or responding.
If you are going to use a flag to tell the thread to stop, then the thread needs to check that flag frequently. If the thread could spend an indefinitely long amount of time doing something else between the checks, then it may never notice that it needs to stop.
If you are going to use Thread.interrupt() then:
Your code should be calling Thread.isInterrupted() to test the thread's "interrupted" status instead of an ad-hoc flag. Furthermore, it should be testing the status regularly.
Your code need to make sure that it handles the InterruptedException and InterruptedIOException properly. This applies all the way up the call stack.
Note that calling Thread.interrupt() doesn't actually interrupt the thread in most cases. In most cases, it just sets a flag that needs to be tested manually. The only cases you get more than that is in certain blocking calls; e.g. Object.wait(...) and some IO calls.
You've left out most of the code where these things ought to happen. The best we can say is that the problem is most likely in code you haven't shown us.

How to stop a java thread gracefully?

I wrote a thread, it is taking too much time to execute and it seems it is not completely done. I want to stop the thread gracefully. Any help ?
The good way to do it is to have the run() of the Thread guarded by a boolean variable and set it to true from the outside when you want to stop it, something like:
class MyThread extends Thread
{
volatile boolean finished = false;
public void stopMe()
{
finished = true;
}
public void run()
{
while (!finished)
{
//do dirty work
}
}
}
Once upon a time a stop() method existed but as the documentation states
This method is inherently unsafe. Stopping a thread with Thread.stop causes it to unlock all of the monitors that it has locked (as a natural consequence of the unchecked ThreadDeath exception propagating up the stack). If any of the objects previously protected by these monitors were in an inconsistent state, the damaged objects become visible to other threads, potentially resulting in arbitrary behavior.
That's why you should have a guard..
The bad part about using a flag to stop your thread is that if the thread is waiting or sleeping then you have to wait for it to finish waiting/sleeping. If you call the interrupt method on the thread then that will cause the wait or sleep call to be exited with an InterruptedException.
(A second bad part about the flag approach is that most nontrivial code is going to be utilizing libraries like java.util.concurrent, where the classes are specifically designed to use interruption to cancel. Trying to use the hand rolled flag in a task passed into an Executor is going to be awkward.)
Calling interrupt() also sets an interrupted property that you can use as a flag to check whether to quit (in the event that the thread is not waiting or sleeping).
You can write the thread's run method so that the InterruptedException is caught outside whatever looping logic the thread is doing, or you can catch the exception within the loop and close to the call throwing the exception, setting the interrupt flag inside the catch block for the InterruptedException so that the thread doesn't lose track of the fact that it was interrupted. The interrupted thread can still keep control and finish processing on its own terms.
Say I want to write a worker thread that does work in increments, where there's a sleep in the middle for some reason, and I don't want quitting the sleep to make processing quit without doing the remaining work for that increment, I only want it to quit if it is in-between increments:
class MyThread extends Thread
{
public void run()
{
while (!Thread.currentThread().isInterrupted())
{
doFirstPartOfIncrement();
try {
Thread.sleep(10000L);
} catch (InterruptedException e) {
// restore interrupt flag
Thread.currentThread().interrupt();
}
doSecondPartOfIncrement();
}
}
}
Here is an answer to a similar question, including example code.
You should not kill Thread from other one. It's considered as fairly bad habit. However, there are many ways. You can use return statement from thread's run method.
Or you can check if thread has already been interrupted and then it will cancel it's work. F.e. :
while (!isInterrupted()) {
// doStuff
}
Make a volatile boolean stop somewhere. Then in the code that runs in the thread, regularly do
if (stop) // end gracefully by breaking out of loop or whatever
To stop the thread, set stop to true.
I think you must do it manually this way. After all, only the code running in the thread has any idea what is and isn't graceful.
You need to send a stop-message to the Thread and the Thread itself needs to take action if the message has been received. This is pretty easy, if the long-running action is inside loop:
public class StoppableThread extends Thread {
private volatile boolean stop = false;
public void stopGracefully() {
stop = true;
}
public void run() {
boolean finished = false;
while (!stop && !finished) {
// long running action - finished will be true once work is done
}
}
}
For a thread to stop itself, no one seems to have mentioned (mis)using exception:
abstract class SelfStoppingThread extends Thread {
#Override
public final void run() {
try {
doRun();
} catch (final Stop stop) {
//optional logging
}
}
abstract void doRun();
protected final void stopSelf() {
throw new Stop();
}
private static final class Stop extends RuntimeException {};
}
A subclass just need to override doRun() normally as you would with a Thread, and call stopSelf() whenever it feels like it wants to stop. IMO it feels cleaner than using a flag in a while loop.

How to stop threads in Java?

I have made a java program with GUI and I want a stop button functionality in which when a user clicks on the stop button, the program must be stopped.
In my program, the main thread starts other 10 threads and I want that whenever the stop button has been clicked all the 10 threads must be stopped before the main thread.
Second, I also want that whenever any thread of those 10 threads is stopped, it must first close all the resources it had opened before like connection to a database etc.
I have implemented the code as answered by ........
Now there is one problem.
My thread class is like this:
public class ParserThread implements Runnable {
private volatile boolean stopped = false;
public void stopTheThread() {
stopped = true;
}
:
:
}
And below is the main thread that starts 10 threads from the function start()
public class Main() {
Thread [] threads;
public void start() {
for(int i = 0; i < 10; i++) {
threads[i] = new Thread(new ParserThread());
}
}
public void stop() {
// code to stop all the threads
}
}
Now I want to call the stop method of the ParserThread to set "stopped = true" to stop the thread. I want this thing to be done for all the 10 threads.
How can I call that stop method. I want it to be done in the stopAllThreads() method of the Main class.
Generally speaking, the way to do this is to have each of the other threads periodically check a flag. Often background threads loop, waiting for work - they just have to check the flag each time they go round a loop. If they're using Object.wait() or something similar to be told that there's more work, the same notification should be used to indicate that the thread should stop too. (Don't just spin until you're stopped - that will suck CPU. Don't just use sleep - that will delay termination.)
That allows all threads to terminate cleanly, releasing resources appropriately. Other options such as interrupt() and the deprecated destroy() method are much harder to control properly, IMO. (Interrupting a thread is better than hard-aborting it, but it has its own set of problems - such as the interruption is only processed at certain points anyway.)
EDIT: In code, it would look something like:
// Client code
for (Task task : tasks) {
task.stop();
}
// Threading code
public abstract class Task implements Runnable {
private volatile boolean stopped = false;
public void stop() {
stopped = true;
}
protected boolean shouldStop() {
return stopped;
}
public abstract void run();
}
Your tasks would then subclass Task. You would need to make it slightly more complicated if you wanted the stop() method to also notify a monitor, but that's the basic idea.
Sample task:
public class SomeTask extends Task {
public void run() {
while (!shouldStop()) {
// Do work
}
}
}
I don't think the answer solve the issue. here the code:
public class SomeTask extends Task {
public void run() {
while (!shouldStop()) {
// Do work
}
}
}
But how to handle if the "Do work" hang and does not return? In this case, the while cannot check the flag. The Thread still cannot stop.
The possible solution to this might be using Process.
Have a controller object which has a flag whether the threads should stop or not and each thread checks the controller periodically and exits if stop button is clicked (for example if you are transferring a file, then after each block is received/sent, check if stop is clicked).

Categories