1
votes

I was trying to stop the running thread, using the volatile variable or atomic variable. But i have some doubts in this. Below is the code i tried.

public class DemoThread {
class DemoRunnable implements Runnable {

    private String name;

    public volatile boolean isRunning = true;

    public DemoRunnable() {
    }

    public DemoRunnable(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public synchronized boolean isRunning() {
        return isRunning;
    }

    public synchronized void setRunning(boolean isRunning) {
        this.isRunning = isRunning;
    }

    @Override
    public void run() {

        System.out.println(" runnable ..." + name + " isRunning "
                + isRunning);

        while (isRunning) {
            int i;
            for (i = 0; i < 100; i++) {
                System.out.println("--------------------> i " + i
                        + " name " + name + " isRunning " + isRunning);
            }
            // if (i > 0) {
            // System.out.println(" volatile not working ");
            // throw new RuntimeException("volatile not working " + name);
            // }
        }
        System.out.println(" run method ends ..." + isRunning);
    }

}

private void demoStop(int count) {
    DemoRunnable runnable1 = new DemoRunnable("" + count);

    Thread t1 = new Thread(runnable1);
    Thread t2 = new Thread(runnable1);

    t1.start();
    t2.start();

    runnable1.isRunning = false;
    // runnable1.setRunning(false);

}

public static void main(String[] args) {
    DemoThread demoThread = new DemoThread();

    for (int i = 0; i < 200; i++) {
        try {
            demoThread.demoStop(i);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

}

Wile executing the code above sometimes the run method containing while loop has been executed many times. Is it any way to stop the while loop from running once the isStopped has been set to false?

interrupt method of thread will not stop the running method.

And atomic boolean, and synchronized method on isStop variable i tried but results are same.

1
Your code actually works. You start t1.start() and the loop can be executed multiple times before runnable1.isRunning = false; is set in the main thread. What do you want to do? - Piotr Gwiazda
The isRunning() and setRunning() methods don't need to be synchronized since the isRunning flag is volatile. - zmb
zmb: i tried synchronized method also but it didn't work, i just posted code with synchronized method, i am not using the setRunning method. - user2724215
Piotr Gwiazda: Once the isRunning is false i need to come out from the while loop in run method. I don't want to continue inside the while loop. - user2724215

1 Answers

1
votes

If your runnable checks isInterrupted, the interrupt() will stop theread as intended.

    @Override
public void run() {
    while (!Thread.currentThread().isInterrupted()) {
        someTask();
        // thread can sleep if you like, add this block  
        try {
            Thread.sleep(10);
        } catch (InterruptedException e) {
            log.warn("Interrupted", e);
            break;
        }
    }
}

Your nested loop does NOT check atomic boolean and naturally won't stop. Anyway, interrupt() is much better than lame boolean flag. See ExecutorService and Future for more details.