I have read the definition of volatile in java, And I run a small test project like below :
public class MainActivity extends AppCompatActivity
{
    static int num = 0;
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Thread readerThread = new Thread(() -> {
            int temp = 0;
            while (true)
            {
                if (temp != num) {
                    temp = num;
                    System.out.println("reader: value of num = " + num);
                }
            }
        });
        Thread writerThread = new Thread(() -> {
            for (int i = 0; i < 5; i++) {
                num++;
                System.out.println("writer: changed value to = " + num);
                //sleep for readerThread to have enough time to read the change of num, since num++ is not atomic
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.exit(0);
        });
        readerThread.start();
        writerThread.start();
    }
}
if I run the main code on Eclipse, the log I get something like this:
writer: changed value to = 1
reader: value of num = 1
writer: changed value to = 2
writer: changed value to = 3
writer: changed value to = 4
writer: changed value to = 5
which is, I guess is right, the result means the reader did't get the value from main memory but the cache memory.
However, if I build the code on real android device by android studio, the log I get is:
I/System.out: reader: value of num = 1
I/System.out: writer: changed value to = 1
I/System.out: reader: value of num = 2
I/System.out: writer: changed value to = 2
I/System.out: writer: changed value to = 3
I/System.out: reader: value of num = 3
I/System.out: writer: changed value to = 4
I/System.out: reader: value of num = 4
I/System.out: writer: changed value to = 5
I/System.out: reader: value of num = 5
seems like without volatile the reader can still get the value from main memory, why the outcome is different between these two?