avocado
avocado

Reputation: 36

Java, Multithreading

I am learning Multithreading and Concurrency in Java on my own. Please help me understand this piece of code. I am creating a thread with a 'stop' boolean variable, the 'run' method loops continuously until the main thread sets the stop variable to true after sleeping for two seconds. However, I am observing this code runs in an infinite loop. What am I doing wrong here?

public class Driver {
    public static void main(String[] args) {
        ThreadWithStop threadWithStop = new ThreadWithStop();
        Thread thread = new Thread(threadWithStop);
        thread.start();

        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        threadWithStop.stopThread();
    }
}

class ThreadWithStop implements Runnable {

    private boolean stop;

    public ThreadWithStop() {
        this.stop = false;
    }

    public void stopThread() {
        this.stop = true;
    }

    public boolean shouldRun() {
        return !this.stop;
    }

    @Override
    public void run() {
        long count = 0L;
        while (shouldRun()) {
            count++;
        }
        System.out.println(count+"Done!");
    }
}

Upvotes: 0

Views: 116

Answers (1)

Hulk
Hulk

Reputation: 6583

Well, it is not guaranteed to stop, but it might. The change you made to the stop by callingstopThread() from the main thread is not guaranteed to be visible to the ThreadWithStop until you synchronize with it somehow.

One way to achieve this would be to protect access to the variable with the synchronizedkeyword - see e.g. the official Oracle tutorial on synchronized methods:

With the following changes, the change to stop is guaranteed to be visible.

class ThreadWithStop implements Runnable {

    private boolean stop;

    public ThreadWithStop() {
        this.stop = false;
    }

    public synchronized void stopThread() {
        this.stop = true;
    }

    public synchronized boolean shouldRun() {
        return !this.stop;
    }

    @Override
    public void run() {
        long count = 0L;
        while (shouldRun()) {
            count++;
        }
        System.out.println(count+"Done!");
    }
}

Upvotes: 2

Related Questions