多线程编程(一) Java内存模型(Java Memory Model)

一、概述

  Java内存模型是Java语言在多线程并发情况下对于共享变量读写(实际是共享变量对应的内存操作)的规范,主要是为了解决多线程可见性、原子性的问题,解决共享变量的多线程操作冲突问题。】

       

  JMM描述了Java程序中各种变量(线程共享变量)的访问规则,以及在JVM中将变量存储到内存中读取出变量这样的底层细节。所有的变量都存储在主内存中,每个线程都有自己独立的工作内存,里面保存该线程使用到的变量的副本(主内存中变量的一份拷贝)

        JMM的两条规定
  1、线程对共享变量的所有操作都必须在自己的工作内存中进行,不能直接从主内存中读写;
  2、不同的线程之间无法直接访问其他线程工作内存中的变量,线程变量值的传递需要通过主内存来完成。

 

 

    (:Java内存模型(JMM) 和 JVM 内存模型区别 :https://www.cnblogs.com/Jomini/p/13176653.html

 

二、并发编程问题

  多线程并发编程会涉及到以下的问题:

  1)原子性:指在一个操作中就是cpu不可以在中途暂停然后再调度,既不被中断操作,要不执行完成,要不就不执行。

  2)可见性:指当多个线程访问同一个变量时,一个线程修改了这个变量的值,其他线程能够立即看得到修改的值。

  3)有序性:程序执行的顺序按照代码的先后顺序执行,多线程中为了提高性能,编译器和处理器的常常会对指令做重排(编译器优化重排、指令并行重排、内存系统重排)。

 

三、解决并发编程

         1)原子性:Java提供了两个高级字节码指令monitorenter和monitorexit,对应的是关键字synchronized,使用该关键字保证方法和代码块内的操作的原子性。

         2)可见性:Java中的volatile关键字提供了一个功能,那就是被其修饰的变量在被修改后可以立即同步到主内存,被其修饰的变量在每次是用之前都从主内存刷新。因此,可以使用volatile来保证多线程操作时变量的可见性。

除了volatile,Java中的synchronized和final两个关键字也可以实现可见性,只不过实现方式不同

  3)有序性:用volatile关键字禁止指令重排,用synchronized关键字加锁。

 

四、指令重新排序

       CPU优化性能

     

 

 

 

 

 

 

 

 

参考:

https://blog.csdn.net/qq_41297896/article/details/89949632

https://blog.csdn.net/zengxiantao1994/article/details/89303290

posted @ 2020-09-06 10:09  抽象Java  阅读(1355)  评论(0编辑  收藏  举报