Home > database >  Java, Multithreading
Java, Multithreading

Time:10-20

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!");
    }
}

CodePudding user response:

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!");
    }
}

CodePudding user response:

Because they share the same variable, and the 'main' thread have the copy of the variable 'stop', the 'thread' thread also have the copy of that. If you change the 'stop', it will not be noticed immediately by 'thread' thread. We can use the keyword 'volatile', so if you change the 'stop', it will be noticed immediately.

private volatile boolean stop;
  • Related