volatile 续
上次的问题在看了一篇博客后有了点理解了
博文地址为
http://www.cnblogs.com/dolphin0520/p/3920373.html
按照文章中写的,在并发编程中,我们通常会遇到以下三个问题:原子性问题,可见性问题,有序性问题
上次的问题应该就是原子性问题了,i++并不能保证是原子性的
对volatile关键字的定义为
一旦一个共享变量(类的成员变量、类的静态成员变量)被volatile修饰之后,那么就具备了两层语义:
1)保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的。
2)禁止进行指令重排序。
所以可以理解为volatile关键字能够保证变量的可见性,但是不能保证操作的原子性
volatile对可见性保证是通过在改变变量即写变量的时候会使其他线程的副本无效,
所以当多个线程都自增操作时,线程A 读取变量,被阻塞,测试其他线程的副本都是有效的,因为A线程并没有写操作,所以B线程取得的变量值是没改变的值,两个线程自增后写回内存实际只自增了一次,所以要保证自增一定发生,要保证操作的原子性,可以用synchronized关键字来保证,或者用Lock锁,或者用AtomicInteger类
最后的问题,volatile关键字的使用场景
synchronized关键字是防止多个线程同时执行一段代码,那么就会很影响程序执行效率,而volatile关键字在某些情况下性能要优于synchronized,但是要注意volatile关键字是无法替代synchronized关键字的,因为volatile关键字无法保证操作的原子性。通常来说,使用volatile必须具备以下2个条件:
1)对变量的写操作不依赖于当前值
2)该变量没有包含在具有其他变量的不变式中
具体的场景文章中写了两个
状态标记量
双重检查