你上面的描述也说了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);
}
}
}
用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);
}
}
}
了解了java的内存模型才知道它是干嘛的
参考下:http://ifeve.com/jmm-faq-dcl/
不知道你看明白没有? 不是2楼说了要了解java的内存模型吗!这里涉及个重排序问题,如果这种现象发生(也即isStoped不是volatile的),那么main线程是可以先赋值isStoped为true的,这样SubThread 线程中的读取i变量的操作可能会看到0,而不是1000;
还有,若isStoped的数据一直缓存在寄存器中,没有刷新到主存中去,SubThread 线程就一直循环下去;你也至多只是看到了正常的情况(若isStoped不是volatile的,上面的代码会有3种情况),至于会不会发生上述其中的情况,你慢慢的测试,但记住运行前要让编译器再次编译。
Java中的同步块和 volatile 变量,两种机制的提出都是为了实现代码线程的安全性。只不过其中 Volatile 变量的同步性较差(但有时它更简单并且开销更低),而且其使用也更容易出错;http://www.ibm.com/developerworks/cn/java/j-jtp06197.html
http://sakyone.iteye.com/blog/668091
1.运算结果不需要变量的当前值,或者能够确保只有单一的线程修改变量的值;
2.变量不需要与其他的状态变量共同参与不变约束;只有符合以上两个原则,才不需要另外的同步确保原子性,否则需要通过加锁来确保原子性。
http://ifeve.com/?x=0&y=0&s=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吗?