1.volatile 最适用一个线程写, 多个线程读的场合.
如果有多个线程并发写操作, 仍然需要使用锁或者线程安全的容器或者原子变量来代替.(摘自 Netty 权威指南)
疑问: 如果只是赋值的原子操作, 是否可以多个线程写?(答案: 可以, 但是一般没有这样的必要, 即没有这样的应用场景)
最经典的使用案例:
- volatile boolean shutdownRequested;
- ...
- public void shutdown() { shutdownRequested = true; }
- public void doWork() {
- while (!shutdownRequested) {
- // do stuff
- }
- }
使用场景 2:
结合使用 volatile 和 synchronized 实现 "开销较低的读 - 写锁"
volatile 允许多个线程执行读操作, 因此当使用 volatile 保证读代码路径时, 要比使用锁执行全部代码路径获得更高的共享度 -- 就像读 - 写操作一样.
- public class CheesyCounter {
- private volatile int value;
- public int getValue() { return value; }
- public synchronized int increment() {
- return value++;
- }
- }
或者
- private volatile long start = System.currentTimeMillis();
- public synchronized long get() {
- return start++;
- }
正确使用 volatile 变量的条件
您只能在有限的一些情形下使用 volatile 变量替代锁. 要使 volatile 变量提供理想的线程安全, 必须同时满足下面两个条件:
对变量的写操作不依赖于当前值.
该变量没有包含在具有其他变量的不变式中.
更多使用场景可参考:
http://www.ibm.com/developerworks/cn/java/j-jtp06197.html
来源: http://www.bubuko.com/infodetail-2993338.html