你上面的描述也说了sychronized可以保证可见性和原子性,volatile只保证了可见性,那就是说sychronized可以实现volatile的作用;但有时不需要考虑原子性,只需保证可见性时,sychronized的实现就比较复杂,而volatile就简单明了,这时就体现volatile存在性了;比如下面的示例:
用volatile来保证isStoped的可见性比使用sychronized要方便简单得多;public class VolatileDemo {
private static int i = 0;
private volatile static boolean isStoped = false;

public static void main(String[] args) {
new SubThread().start();
i = 1000;
isStoped = true;
} private static class SubThread extends Thread{
public void run(){
while(!isStoped){
System.out.println(Thread.currentThread().getName());
Thread.yield();
}

System.out.println(i);
}
}
}

解决方案 »

  1.   

    volatile只是保证了内存的可见性,并不能做同步
    了解了java的内存模型才知道它是干嘛的
    参考下:http://ifeve.com/jmm-faq-dcl/
      

  2.   

    加不加volatile, 执行结果都一样啊
      

  3.   

    加不加volatile, 执行结果都一样啊
    不知道你看明白没有? 不是2楼说了要了解java的内存模型吗!这里涉及个重排序问题,如果这种现象发生(也即isStoped不是volatile的),那么main线程是可以先赋值isStoped为true的,这样SubThread 线程中的读取i变量的操作可能会看到0,而不是1000;
    还有,若isStoped的数据一直缓存在寄存器中,没有刷新到主存中去,SubThread 线程就一直循环下去;你也至多只是看到了正常的情况(若isStoped不是volatile的,上面的代码会有3种情况),至于会不会发生上述其中的情况,你慢慢的测试,但记住运行前要让编译器再次编译。
      

  4.   

    存在即合理,存在自然有它存在的理由的!
    Java中的同步块和 volatile 变量,两种机制的提出都是为了实现代码线程的安全性。只不过其中 Volatile 变量的同步性较差(但有时它更简单并且开销更低),而且其使用也更容易出错;http://www.ibm.com/developerworks/cn/java/j-jtp06197.html
    http://sakyone.iteye.com/blog/668091
      

  5.   

    volatile的性能大多数情况比sychronized和lock好,但是Java虚拟对sychronized和lock进行很多优化,这种差距会越来越小,最重要的是volatile的使用情况很受限制,我引用一下《深入理解Java虚拟机》的原话:
    1.运算结果不需要变量的当前值,或者能够确保只有单一的线程修改变量的值;
    2.变量不需要与其他的状态变量共同参与不变约束;只有符合以上两个原则,才不需要另外的同步确保原子性,否则需要通过加锁来确保原子性。
      

  6.   

    http://ifeve.com/concurrency-visibility/
    http://ifeve.com/?x=0&y=0&s=volatile
      

  7.   

    在实际编程中volatile使用得比较少
      

  8.   

    加不加volatile, 执行结果都一样啊
    不知道你看明白没有? 不是2楼说了要了解java的内存模型吗!这里涉及个重排序问题,如果这种现象发生(也即isStoped不是volatile的),那么main线程是可以先赋值isStoped为true的,这样SubThread 线程中的读取i变量的操作可能会看到0,而不是1000;
    还有,若isStoped的数据一直缓存在寄存器中,没有刷新到主存中去,SubThread 线程就一直循环下去;你也至多只是看到了正常的情况(若isStoped不是volatile的,上面的代码会有3种情况),至于会不会发生上述其中的情况,你慢慢的测试,但记住运行前要让编译器再次编译。
    我对这句很不理解 :
    那么main线程是可以先赋值isStoped为true的,这样SubThread 线程中的读取i变量的操作可能会看到0,而不是1000;
    这是在说 isStoped为true subThread读取i时为0吗? 
      

  9.   

    建议楼主看看 java并发编程实战 这本书。二楼的例子也是书中提到的,涉及到重排序问题,在缺少同步的情况下,从代码逻辑是看不出结论的。volatile用处除了二楼提到的,还有在并发下的set和get方法,单例模式中的双重加锁的写法中也用到volatile
      

  10.   

    看JDK源码,很多都是volatile实现的。