JAVA volatile 关键字详解
来源:互联网 发布:淘宝家具店排名 编辑:程序博客网 时间:2024/06/11 21:09
volatile可以简单理解为确保多线程安全的手段,但现实情况下,volatile并不能代替synchronized。
volatile有两个作用:
作用1:在多线程工作模式下,确保一个线程修改了volatile修饰的变量,对其他线程立刻可见。但该机智并不能保证被volatile修饰的变量的正确性,看下面的例子↓
public static volatile int race = 0;
public static void main(String[] args) {
Thread[] threads = new Thread[10];
//启动10个线程做累加工作
for (int i = 0; i < threads.length; i++) {
threads[i] = new Thread(new Runnable() {
public void run() {
for (int j = 0; j < 10000; j++) {
race++;
}
}
});
threads[i].start();
}
//等待所用线程执行完成
while(Thread.activeCount()>1)
Thread.yield();
//此处的值,并非我们认为的100000,会是一个小于100000的值
System.out.println(race);
}
为什么不是100000呢?这与jvm的执行字节码的方式有关,race++操作,在编译为字节码后,会产生4个操作,
getstatic
iconst_1
iadd
putstatic
第一个操作是将race变量push到操作栈顶,这个时候因为变量定义为volatile,所以值是正确的,iconst_1 将1常量放入操作栈顶,但下一个指令,iadd,putstatic时,其他线程很可能已经改变了race的值,操作栈又是线程私有的内存空间,所以,结果出现了偏差。
作用2:禁止指令的重新排序
这个是对于虚拟机层面的表述,普通变量仅仅会在方法执行过程中,所有依赖赋值结果的地方,都已经进行正确的赋值操作,但并不能保证赋值的顺序跟代码书写的一样,volatile修饰的变量,确实禁止对执行指令的重新排序优化。该作用在现实开发中应用不大,
int a = 1;
int b = 3;
上面的两行代码,并不能保证a一定比b先赋值。
我的总结是:volatile定义的变量不应该进行频繁的赋值操作,或者说,仅仅有一个线程负责写入,其他线程负责读取,做到一个广播的效果,如下面的伪代码:
public static volatile boolean init = false;
Thead1.setInit(true);
Thead2.run()
{
while(true)
if(init)
break;
}
- java volatile关键字详解
- Java volatile关键字详解
- JAVA volatile 关键字详解
- Java volatile关键字详解
- Java Volatile 关键字详解
- 详解java中的volatile关键字
- Java中volatile关键字详解
- Java中的Volatile关键字详解
- 详解java中volatile关键字
- Java中Volatile关键字详解
- Java中Volatile关键字详解
- Java中Volatile关键字详解
- Java中Volatile关键字详解
- Java中Volatile关键字详解
- Java中Volatile关键字详解
- Java中Volatile关键字详解
- Java中Volatile关键字详解
- 【Java多线程】Volatile关键字详解
- 第一行代码笔记,第六章-----详解数据存储
- 第十课 使用java开发spark 实战
- android 自定义View 的详细介绍
- 读取plist文件中的数据
- Ethercalc中的Post commands
- JAVA volatile 关键字详解
- 建立,保持时间 什么时候用?
- 【数据结构】算法10.6-10.8 快速排序
- Mediinfo.DBAccess.DBSQLException
- Itellij Idea 常用快捷键
- operator int () const; // 类型转换操作符函数(转整型)
- 第二章:java学习基础语法
- Fast Exact Search in Hamming Spacewith Multi-Index Hashing
- 【关于科研】自己认为的一些做好科研的建议