简体   繁体   中英

happens-before relationship does not work as expected using "volatile"

int x,y;
volatile int z;

public static void main(String[] args) {
    ThreadPoolExecutor pool = (ThreadPoolExecutor)Executors.newFixedThreadPool(5);
    MainTest mission = new MainTest();
    pool.execute(new MissionRead(mission));

    pool.execute(new MissionWrite(mission));
            pool.execute(new MissionWrite(mission));

    pool.shutdown();
}

public void set() {
    System.out.println("set start");
    x++;

    y++;z++;

    System.out.println("set end");

}

public void get() {
    System.out.println(Thread.currentThread().getName() +": get start");
    System.out.println(Thread.currentThread().getName() +": z is " + z);
    System.out.println(Thread.currentThread().getName() + ": x is " +  x);
    System.out.println(Thread.currentThread().getName() +": y is " + y);
    System.out.println(Thread.currentThread().getName() +": get end");

}

output: pool-1-thread-1: get start
set start
set end
set start
set end
pool-1-thread-1: z is 0
pool-1-thread-1: x is 2
pool-1-thread-1: y is 2
pool-1-thread-1: get end

expected output: pool-1-thread-1: get start set start
set end
set start
set end
pool-1-thread-1: z is 2
pool-1-thread-1: x is 2
pool-1-thread-1: y is 2
pool-1-thread-1: get end

why the output does not display the updated value of z with volatile keywords.

This is because being volatile would simply force a read on the main memory for any atomic action done to/with it, but z++ is equivalent to z = z + 1 which means there are 2 actions in there: a read operation and a write operation. Multiple threads can still read/write the value in between these 2 operations.

I guess you are looking for something like this: Use the synchronized keyword in your method. This ensures that the commands in this method are all executed as if it was only one statement. So nothing happens inbetween these statements.

public synchronized void set() {
    System.out.println("set start");
    x++;
    y++;
    z++;
    System.out.println("set end");
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM