JAVA线程之内存可见性
来源:互联网 发布:tensorflow gpu whl 编辑:程序博客网 时间:2024/06/01 17:42
今天学到了java线程之内存可见这一章。现在来进行总结,理一下思维;
首先什么叫做内存可见性,内存可见性就是指我们在多线程的程序中,一个共享变量的修改能够被另一个线程所能及时看到,并能及时引用,我觉得这就叫做内存可见性;
我们都知道在一个线程中共享变量的值都存储在主内存中,而当我们启动线程的时候,jvm会为我们再线程中创建一个工作内存,这个工作内存中,存储的相当于是主内存中的副本。当线程1的值要发生修改时,它会先去修改工作内存1中的值,然后再去刷新主内存中的值。但是这样做就会存在一些问题,比如线程1工作内存的值,刚好发生了修改。而线程2工作内存的值也发生了修改,他们都会去刷新主内存的值,假设两个工作同时执行,主内存的值有可能发生一次,这就是我们所说的并发特性里面的内存不可见性。下面我们写一个程序来分析一下
private int sum; //全局变量
private class NewThread extends Thread{
@Override
public void run() {
for(int i=0;i<10;i++){
sum++;
}
System.out.println(sum);
super.run();
}
}
public static void main(String[] args) {
MyThread mt=new MyThread();
for(int i=0;i<10;i++){
mt.new NewThread().start();
}
}
最后打印一下结果,大部分都是10的倍数。
10
30
20
40
50
70
60
90
100
80
但是我们多运行几遍就会有其他的不同结果,这就是由于并发所导致的。
java的不可见性主要是有两种原因导致的,一个是并发,还有一个就是重排序,上面的一个例子就是并发,下面我们来看一个重排序的案例
public class SynThread {
public boolean flag;
public int number;
public int sum;
public void read(){
flag=true; //1.1最开始执行的把flag的值改变为true;
number=3; //1.2把number的值变为3
}
public void write(){
if(flag){ //2.1验证flag是否为true
sum=number*2; //2.3为true则执行下一步把number的值乘以2得到sum
}
System.out.println(sum); //2.3打印结果应该为6
}
private class myThread extends Thread{
private boolean flag;
public myThread(boolean flag) {
super();
this.flag = flag;
}
@Override
public void run() {
if(flag){
write();
}else{
read();
}
}
}
public static void main(String[] args) {
SynThread st=new SynThread();
st.new myThread(true).start();
st.new myThread(false).start();
}
按照正常的逻辑来说打印的sum值应该为6,但是也有其例外的地方,那就是java的重排序,只要执行
结果符合as-if-serial语义
as-if-serial语义的意思指:不管怎么重排序(编译器和处理器为了提高并行度),(单线程)程序的执行结果不能被改变。比如说语句没有算法关系的,没有依赖关系的就有可能会执行重排序;上面的程序有可能按照顺序执行,也有可能先执行1.2,1.1,2.2,2.1,2.3,也有可能先执行2再执行1,这样结果就会发生改变其值就会变成0;
我们可以通过两个简单的方法来实现java内存的可见性,一个是同步关键字.synchronized。
加上这个关键字之后,不管程序怎么执行,他都会保证一个线程执行完后,才会执行下一个程序,而且他具有原子性,所以能够实现能存可见性,还有一个就是通过volitile关键字。这个关键字不能保证同步但能实现重排序,其原理就是用它修饰的变量,在线程内存修改的时候,必须马上去刷新主内存中的值,而当其它线程要取得主内存中的值时,JVM必须保证其内存中的值必须是最新值.所以可以保证其内存可见性.
- JAVA线程之内存可见性
- JAVA 线程之内存可见性
- Java多线程之内存可见性
- Java多线程之内存可见性
- JAVA多线程之内存可见性笔记
- Java多线程之内存可见性
- Java多线程之内存可见性
- Java多线程之内存可见性
- 浅谈java多线程之内存可见性
- Java多线程之内存可见性
- Java多线程之内存可见性
- Java多线程之内存可见性
- Java多线程之内存可见性
- java多线程之内存可见性
- 细说Java多线程之内存可见性
- Java多线程之内存可见性
- Java多线程之内存可见性
- Java可见性之内存模型
- 温州大妈开包厢吸毒 网友:广场舞跳腻了?
- C++通过输入数来确定一个数组的动态大小
- System.arraycopy()
- C++ template的一些高级用法(元编码,可变参数,仿函数,using使用方法,. C++ 智能指针)
- 黑马程序员——继承和多态
- JAVA线程之内存可见性
- 删除win7中的VPN
- VS2005+WDK7600开发环境
- 国际化
- hihocoder1037(记忆化搜索)
- 利用Java API生成50到100之间的随机数
- CCF推荐国际会议和期刊
- 8. PHP 布尔类型
- J2EE学习笔记 整理