0

I have a thread running when flag is true,but when I change the flag to false, it does not go to die.

public static void main(String[] args)
    {
        try
        {
            MyThread mt = new MyThread();
            mt.start();
            Thread.sleep(1000);
            mt.setRunning(false);
            System.out.println("set running false");
        }
        catch (InterruptedException e)
        {
            e.printStackTrace();
        }
    }

    public static class MyThread extends Thread
    {
        private boolean isRunning = true;

        public boolean isRunning()
        {
            return isRunning;
        }

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

        public void run()
        {
            System.out.println("run");
            while (isRunning == true){
            }
            System.out.println("run over!");
        }
    }

I know defining "isRunning" as volatile will solve the problem,but when not volatile, "isRunning" shouldn't be visible at some point to MyThread?

ccc
  • 65
  • 1
  • 5

2 Answers2

3

This is due to visibility reasons.

Make your variable volatile:

volatile private boolean isRunning = true;

See What is the volatile keyword useful for for more details.

I know defining "isRunning" as volatile will solve the problem,but when not volatile, "isRunning" shouldn't be visible at some point to MyThread?

It's the value change of isRunning that you need to make visible to MyThread when the main thread changes it. Otherwise it might just continue seeing the cached value of true.

Kartik
  • 7,677
  • 4
  • 28
  • 50
  • I know that using volatile will make the variable visible at once, but my question is without using volatile, I think the variable change will be visible to the thread in the future at some point,but the result seems the change of the variable will never be visible... – ccc Jun 21 '19 at 05:46
  • @ccc there is no such guarantee. The updated value might **never** be visible to another thread. This is mentioned in Java Concurrency in Practice book. – Kartik Jun 21 '19 at 06:36
0

There are two threads here. Every thread has a cache. When you don't add volatile, the thread reads the value from the owner cache. So, myThread.isRunning is true. By using volatile, the owner thread can forcibly write to memory and refresh the cache.

ordonezalex
  • 2,645
  • 1
  • 20
  • 33