volatile variable is not giving expected output

ASR :

I read that volatile variable copy will shared by all the threads and once completion of the execution, the update value will get by every thread,But in the following program using thread pool not giving the output which I expected, can any one tell me the reason?

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

class Task implements Runnable{
    volatile int v1=10;

    private String name;

    public Task(String name) {
        this.name=name;
    }

    public  synchronized void  run() {
        v1=v1+10;
        System.out.println(name +"is entered "+v1);

    }

}
public class ThreadPoolTest {

    public static void main(String[] args) {
        Runnable r1 = new Task("Thread 1"); 
        Runnable r2 = new Task("Thread 2"); 
        Runnable r3 = new Task("Thread 3"); 

        ExecutorService executor = Executors.newFixedThreadPool(5);

        executor.execute(r1);
        executor.execute(r2);
        executor.execute(r3);

        executor.shutdown();  
    }
}

outPut:

Thread 1is entered 20
Thread 2is entered 20
Thread 3is entered 20

but if we change from volatile to static its giving below output:

Thread 1is entered 20
Thread 3is entered 30
Thread 2is entered 40
Fullstack Guy :

The observed result is correct as you are creating three separate Task instances who are having their own copy of the name variable.

So although they are volatile the values are not updated by other threads the thread executing the particular instance is the one which is updating the v1 field.

If the v1 is made static then it becomes a class member so obviously the threads will update the same copy of the variable v1.

Instead of using synchronized on the run method, we can use the AtomicInteger to safely update and fetch the value.

class Task implements Runnable{
    private final AtomicInteger v1 = new AtomicInteger(10);

    private String name;

    public void run() {
       System.out.println("Thread is: " + Thread.currentThread().getName() + " " + v1.addAndGet(10));
    }

}
public class ThreadPoolTest{

    public static void main(String[] args) {
        Runnable r1 = new Task();
        ExecutorService executor = Executors.newFixedThreadPool(3);
        executor.execute(r1);
        executor.execute(r1);
        executor.execute(r1);
        executor.shutdown();
    }
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=114621&siteId=1