Search code examples
javavariablesvolatile

Display difference between volatile and usual variable in Java


I am trying to create an example to display the difference between volatile and usual variables like:

package main;

public class TestVolatile extends Thread {

    public int l = 5;
    public volatile int m = -1;

    public TestVolatile(String str) {
        super(str);
    }

    public void run() {
        int i = 0;
        while ((l > 1) && (l < 10)) {
            if (m >= 0) {
                m++;
            }
            i++;
            l = 5;
            System.out.println("5=" + i + " m=" + m);
        }

    }

    public static void main(String[] args) throws InterruptedException {
        TestVolatile tva = new TestVolatile("ThreadA");

        tva.start();
        sleep(5);
        synchronized (tva) {
            tva.m = 5;
            tva.l = 10;
        }
    }

}

So m is volatile, l is not. I suppose that exiting from the while loop depends on the value of l.
Because the value of l is not volatile - m will be incremented at least 1 time after l has been assigned 5. But I have run the code 10 times and always m==5.
So I suppose that I am wrong. How to fix this problem? Thank you.

Thanks for answers, but not all run well. I set like:

volatile int x = 0;
volatile int y = 0;

So now the variables have to be the same! But that is not the case.

x: 346946234 y: 346946250
x: 346946418 y: 346946422
x: 346946579 y: 346946582
x: 346946742 y: 346946745
x: 346946911 y: 346946912

Solution

  • You are synchronizing the main thread and your test thread. Therefore Java guarantees to make any changes visible performed by the other thread.

    Btw, it is impossible to construct an example which deterministically shows a difference between volatile and non-volatile. The best you can hope is to get a program which shows the difference with a quite high probability. If the threads run interleaved on the same core. You won't be able to show any difference at all.

    The following program shows on my computer the difference between volatile and non-volatile variables.

    public class ShowVolatile {
    
        final static int NUM_THREADS = 1;
    
        int x = 0;
        volatile int y = 0;
    
        public static void main(String... args) {
    
            final ShowVolatile sv = new ShowVolatile();
    
            for (int i=0; i< NUM_THREADS; i++) {
                new Thread(new Runnable() {
                    public void run() {
                        while (true) {
                            sv.x += 1;    
                            sv.y += 1;    
                        }
                    }
                }).start();
            }
    
    
            while (true) {
                System.out.println("x: " + sv.x + " y: " + sv.y);
            }
        }
    
    }
    

    If you increase the number of threads you will see additional synchronization misses. But a thread count of 1 is enough. At least on my hardware a Quad-Core i7.