007.多线程-Java内存模型

版权声明:本文为博主原创文章,允许转载,请标明出处。 https://blog.csdn.net/qwdafedv/article/details/84074639

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

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

Java内存模型中规定,所有的变量都存储在主内存中,
对所有线程都是共享的。

而每个线程都有自己的工作内存。
工作内存中保存的是对主内存中某些变量的拷贝。

不同线程无法访问对方的工作内存,
线程间通信必须通过主内存来完成。

线程对所有变量的操作(读取、赋值等)必须在工作内存中进行,
首先,将变量冲主内存拷贝到自己的工作内存,
然后,对变量进行操作,操作完成后,再将变量更新到主内存。


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


线程安全问题

当多个线程同时操作(读取+赋值)一个数据的时候,
可能因为工作内存没有及时刷新到主内存 (线程何时将工作内存刷新到主内存是不确定的),
造成线程不安全。


多线程的三大特性

  • 原子性

    • 原子性指的是一个操作是不可中断的,即使是在多线程环境下,一个操作一旦开始就不会被其他线程影响

      int i=1;//原子操作,直接赋值,要么赋值成功,要么赋值不成功
      
      i++;//非原子操作,这里包含了多步:读取i的值;将i的值加1;将新值赋值给i
      
  • 可见性

    扫描二维码关注公众号,回复: 4079174 查看本文章
    • 当多个线程访问同一个变量时,一个线程修改了这个变量的值,其他线程能够立即看得到修改的值。

      解决可见性问题,一般采用volatile
      volatile可以保证可见性,但是却不能保证原子性
      
      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,
          * 使用该变量对其他线程立即可见,
          * 从而达到线程安全的目的。
          */
      }
      
  • 有序性

    • 程序执行的顺序按照代码的先后顺序执行。

      volatile关键字另一个作用就是禁止指令重排优化,
      从而避免多线程环境下程序出现乱序执行的现象
      

猜你喜欢

转载自blog.csdn.net/qwdafedv/article/details/84074639