2
public class VolatileDemo implements Runnable{

private static volatile int count = 0;
private Random random = new Random();

public static void main(String[] args) {
    for(int i=0;i<1000;i++){
        new Thread(new VolatileDemo()).start();
    }
    while(Thread.activeCount()>1){
        Thread.yield();
    }
    System.out.println(count);
}

@Override
public synchronized void run() {
    try {
        Thread.sleep(random.nextInt(1000));
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    System.out.println(Thread.currentThread().getName()+" " + count++);
}

}

After running (in jdk1.8), the answer is not 1000. Please tell me the reason.

Alex Shesterov
  • 26,085
  • 12
  • 82
  • 103
  • 1
    Hint: try replacing that count to type `AtomicInteger` and call the corresponding methods on that object. See what happens then. – GhostCat Sep 14 '18 at 10:18
  • synchronized on the method means that there cannot be two calls at the same time for the same object https://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html you can try to extract the (new VolatileDemo) outside of the for – vmrvictor Sep 14 '18 at 10:22
  • @vmrvictor. Thanks, I always get that bit confused. @aigaoxiaode if you synchronize the `count++` line on a static object, you get 1000. – Steve Smith Sep 14 '18 at 10:25
  • @SteveSmith, he used the `synchronized` keyword on the non-static method `run`. This means that `this` (in his case a `VolatileDemo` instance) will be used as a monitor. And as he's creating multiple `VolatileDemo` instances, the monitors are all different and synchronization has no effect. A `synchronized(lockObject) {...}` block with a `private static final Object lockObject = new Object()` would have solved the problem. An `AtomicInteger` would also do. – Alex Shesterov Sep 14 '18 at 10:42
  • @SteveSmith thankyou for the docs,however if I changed the number of active thread to 0,the program would never stop since the main thread is still alive. – laigaoxiaode Sep 14 '18 at 16:16
  • @vmrvictor thanks,what you said is exactly what I need – laigaoxiaode Sep 14 '18 at 16:27
  • @AlexShesterov thanks all the same – laigaoxiaode Sep 14 '18 at 16:28

1 Answers1

0

Volatile is not secure for 'increment' operations, because it is not atomic(read, increment, write) Volatile is only guarantees that changes made on variable will be avalable to all threads reading it.

For secure increment operations you should you 'Atomic' variables instead

SHaaD
  • 141
  • 2
  • 13