前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >007.多线程-Java内存模型

007.多线程-Java内存模型

作者头像
qubianzhong
发布2018-12-13 16:12:03
3390
发布2018-12-13 16:12:03
举报
文章被收录于专栏:行者常至行者常至

版权声明:本文为博主原创文章,允许转载,请标明出处。 https://cloud.tencent.com/developer/article/1372004

Java内存模型 ( Java Memory Model , JMM )

JMM主要是规定了线程与内存之间的一些关系。

Java内存模型中规定,所有的变量都存储在主内存中,

对所有线程都是共享的。

而每个线程都有自己的工作内存。

工作内存中保存的是对主内存中某些变量的拷贝。

不同线程无法访问对方的工作内存,

线程间通信必须通过主内存来完成。

线程对所有变量的操作(读取、赋值等)必须在工作内存中进行,

首先,将变量冲主内存拷贝到自己的工作内存,

然后,对变量进行操作,操作完成后,再将变量更新到主内存。

上图来源于 https://blog.csdn.net/javazejian/article/details/72772461


线程安全问题

当多个线程同时操作(读取+赋值)一个数据的时候,

可能因为工作内存没有及时刷新到主内存 (线程何时将工作内存刷新到主内存是不确定的),

造成线程不安全。


多线程的三大特性

  • 原子性
代码语言:txt
复制
-  原子性指的是一个操作是不可中断的,即使是在多线程环境下,一个操作一旦开始就不会被其他线程影响 int i=1;//原子操作,直接赋值,要么赋值成功,要么赋值不成功  i++;//非原子操作,这里包含了多步:读取i的值;将i的值加1;将新值赋值给i
 
  • 可见性
代码语言:txt
复制
- 当多个线程访问同一个变量时,一个线程修改了这个变量的值,其他线程能够立即看得到修改的值。有序性
代码语言:txt
复制
-  程序执行的顺序按照代码的先后顺序执行。 volatile关键字另一个作用就是禁止指令重排优化, 从而避免多线程环境下程序出现乱序执行的现象
 

volatile

  • 保证线程之间的可见性
  • 禁止指令重排序优化

普通的共享变量不能保证可见性,因为普通的共享变量被修改之后,

什么时候被写入主内存是不确定的。

当其他线程去读取时,此时内存中可能还是原来的旧值,因此无法保证可见性。

当写一个volatile变量时,JMM会把该线程对应的工作内存中的共享变量值刷新到主内存中,

当读取一个volatile变量时,JMM会把该线程对应的工作内存置为无效,那么该线程将只能从主内存中重新读取共享变量。

volatile保证了线程之间可见,但不保证原子性。

代码语言:javascript
复制
public class VolatileSafe {

    volatile boolean close;

    public void close(){
        close=true;
    }

    public void doWork(){
        while (!close){
            System.out.println("safe....");
        }
    }
    /**
    * 由于对于boolean变量close值的修改属于原子性操作,
    * [对于非原子性操作,应使用synchronized关键字来保证线程安全]
    * 因此可以通过使用volatile修饰变量close,
    * 使用该变量对其他线程立即可见,
    * 从而达到线程安全的目的。
    */
}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018年11月15日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Java内存模型 ( Java Memory Model , JMM )
  • 线程安全问题
  • 多线程的三大特性
  • volatile
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档