发布于2021-03-13 13:25 阅读(836) 评论(0) 点赞(7) 收藏(5)
(1)volatile
关键字只能修饰变量。
(2)volatile
关键字是线程同步的轻量级实现
,被volatile
修饰的变量,具有可见性
,即每次线程使用这个变量时,都是读取主内存中这个变量的最新值。
(3)同时被volatile
修饰的变量还具有有序性
,为了性能优化,jvm
在不改变正确语义的情况下,会允许编译期和处理器对指令序列进行重新排序,而volatile
可以阻止jvm
重新排序。
Test test = new Test();
这行代码是分为三部执行的
1.为test分配内存空间;
2.初始化test;
3.将test指向分配的内存地址;
由于JVM
有指令重排的特性,所有上述步骤可能为1->3->2
,在逻辑上是可行的。如果线程A执行了1和3,线程B如果这时判断test
是否有值,会得到有值的结果,但是使用test
却会报错,因为test
没有初始化。所有volatile
可以组织指令重排,使之按照1->2->3
的顺序执行。
(4)volatile
可以保证变量的可见性
,但是不能保证原子性
。即多线程的情况不能保证线程安全,可能会出现脏读
的情况。
在当前的Java内存模型
中,线程可以把变量保存为本地内存
(如机器的寄存器)中,线程操作该变量时就是从本地内存中取值,而不是从主内存
中取值,如果另一个线程在主内存中修改了这个变量的值,当前线程是感知不到的,会造成数据的不一致问题,也就是脏读
。
如果该变量使用了volatile
修饰的话,那么线程每次操作该变量都会直接从主内存中读取数据、写入数据。让数据在线程间有可见性
。
package com.kk.first.thread;
public class TestVolatile extends Thread {
private static volatile Integer a = 0;
@Override
public void run() {
int i = 0;
while (i < 1000) {
add();
i++;
}
}
private static void add() {
a++;
}
public static void main(String[] args) {
TestVolatile tv = new TestVolatile();
for (int i = 0; i < 10; i++) {
Thread t = new Thread(tv);
t.start();
}
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(a); // 7595
}
}
如果volatile
能保证原子性
,那么执行结果a应为10000,但是结果却小于10000。所以volatile
修饰的变量并不能保证原子性
。虽然其修饰的变量是直接从主内存中读取数据,但是多个线程竞争的话,并且对数据有计算操作的话,如volatile修饰变量a在主内存中值为0,A线程读取的时候值为0,在A线程执行操作为加1,这时B线程也读取a的值,此时A线程执行的结果还没有写入到主内存中,所以B线程读取到的值为a=0
,B线程也做+1操作。两个线程都执行完,将值写入主内存中。最终得到a的值为1,也就是两个线程都对a做的+1的操作,但是最后的结果却是a=1。
所以volatile经常和synchronized关键字不是互斥的,是互补的,它们经常配合使用,比如通过双重检验锁实现线程安全的单例模式
。
详细可见这篇博文Volatile和Synchronized关键字实现单例模式(线程安全)
synchronized相关详解Java高并发之synchronized关键字
作者:天使的翅膀
链接:http://www.javaheidong.com/blog/article/114168/fe9fba1f18b311cd543e/
来源:java黑洞网
任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任
昵称:
评论内容:(最多支持255个字符)
---无人问津也好,技不如人也罢,你都要试着安静下来,去做自己该做的事,而不是让内心的烦躁、焦虑,坏掉你本来就不多的热情和定力
Copyright © 2018-2021 java黑洞网 All Rights Reserved 版权所有,并保留所有权利。京ICP备18063182号-2
投诉与举报,广告合作请联系vgs_info@163.com或QQ3083709327
免责声明:网站文章均由用户上传,仅供读者学习交流使用,禁止用做商业用途。若文章涉及色情,反动,侵权等违法信息,请向我们举报,一经核实我们会立即删除!