1
public class VolatileOne {
    private static boolean ready ;
    private static int number ;

    private static class ReaderThread extends Thread{
        @Override
        public void run() {
            while (!ready){
                Thread.yield();
            }
            System.out.print(number);
        }
    }

    public static void main(String[] args) {
        new ReaderThread().run();
        ready = true;
        number = 50;
    }
}

After running this code, the program does not stop, which is obvious because the thread backs up variables ready into the memory of its own process. When I use volatile keyword to modify read

private volatile static boolean ready ;

the read variable will not be copied into process memory at this time. But the program can't stop. What's the reason? Is it related to the static keyword?

If you want the program to output 50 and return, what should you do?

Michael
  • 41,989
  • 11
  • 82
  • 128
Zhe Ma
  • 45
  • 1
  • 6
  • 8
    Never call `run()` on a thread. – MC Emperor Feb 25 '19 at 14:49
  • There are three problems in the code, so I do not think it's a duplicate. – xingbin Feb 25 '19 at 14:55
  • @孙兴斌 - It can be a duplicate of multiple questions. – Stephen C Feb 25 '19 at 15:42
  • @MCEmperor, Calling `t.run()` may be an example of extremely poor _style_, and it may not do what the OP thinks it does, but it does _something,_ and that might be a thing that some programmer actually wants to do. Instead of just saying, "Never call run()..." you might also say why not. – Solomon Slow Feb 25 '19 at 15:53
  • @ZheMa, Your program does not create any thread. A `Thread` object is not a thread. A `Thread` object is a _handle_ that your program can use to create and manage a thread, but the actual thread is not created until your program calls `.start()`. You normally never write any call to the `run()` method. Your `run()` method gets called _automatically_, inside the new thread, after the thread has been started. – Solomon Slow Feb 25 '19 at 15:56
  • @SolomonSlow I indeed could have better included a link to [the very first Google search result](https://beginnersbook.com/2015/03/why-dont-we-call-run-method-directly-why-call-start-method/) of my exact words, which reveals the why. – MC Emperor Feb 25 '19 at 16:00

1 Answers1

4
  1. You need call start to execute the code in another thread. Check this for the difference between run and start.

  2. Call join to wait the ReaderThread finish.

  3. volatile keyword can build a happens-before relationship between the write and the read thread, you can put number = 50; before ready = true;, which makes sure the reader will notice number is 50 when it notice ready is true.

Example:

Thread reader = new ReaderThread();
reader.start();
number = 50;
ready = true;
reader.join();
xingbin
  • 27,410
  • 9
  • 53
  • 103