Volatile 和 synchronized 的区别

Difference between Volatile and synchronized

我已经执行了下面一段代码,期望计数为 20000。我已将计数声明为 volatile,但输出始终不正确。

package threading;

public class Demo5 {
    private volatile int count =0;
    public static void main(String[] args){
        Demo5 d = new Demo5();
        d.doWork();
    }

    public void doWork(){
        Thread t1 = new Thread(new Runnable() {
            public void run() {
                for(int i=0; i<10000; i++){
                    count++;
                }

            }
        });
        Thread t2 = new Thread(new Runnable() {
            public void run() {
                for(int i=0; i<10000; i++){
                    count++;
                }

            }
        });
        t1.start();
        t2.start();

        try{
            t1.join();
            t2.join();
        }
        catch (InterruptedException  e) {
            e.printStackTrace();
        }
        System.out.println(count+" is count");
    }
}

后来我尝试通过将其放入同步方法中来使计数成为同步的,并且它工作正常。

public synchronized void increment(){
        count++;
    }

有人能告诉我什么时候应该使用 volatile 什么时候使用 synchronized 吗?

synchronized 中,您将增量和设置操作包含在同一临界区中。使用 volatile 增量和集合分别受到保护。这意味着一个线程可以递增,然后另一个,然后一个可以设置,然后另一个,不一定按照它们递增的顺序。 volatile只能协调单个动作; synchronized 可以协调动作序列 。