from:effective java & thinking in java
互斥(mutex):当一个对象被一个线程修改时,可以阻止另外一个线程观察到对象内部不一致的状态。对象被创建的时候就处于一致的状态,当有方法访问它的时候,它就被锁定了。
同步:不仅可以阻止一个线程看到对象处于不一致的状态(互斥),它还可以保证进入同步方法或者同步代码块的每个线程,都看到由同一个锁保护的之前的最后修改效果(可视)。
synchronized保证同一时刻,只有一个线程可以执行某个方法,或者某个同步块。
原子性:一旦操作开始,那么它就一定可以在可能发生的线程切换前执行完毕,即不能被线程调度机制中断。但并不保证一个线程写入的值对于另外一个线程是可见的。
读写long和double之外的基本数据类型都是原子操作。
volatile可以保证任何一个线程在读取该域的时候都将看到最近刚刚写入的值(可视)。
总之,当多个线程共享可变数据的时候,每个读或者写数据的线程都必须执行同步。否则,就无法保证一个线程所做的修改可以被另外一个线程获知。如果只需要线程之间的交互通信,而不需要互斥,volatile修饰符是一种可以接受的同步形式,但正确地使用它可能需要一些技巧。