1.在开始多线程之前,我们先来聊聊计算机的缓存

  计算机处理一个程序需要cpu处理器与存储设备的交互。但是在计算机发展的过程中,cpu处理器的处理速度不断提高,而存储设备的读写速度却没有得到与cpu同样速度的发展。为了解决这个问题,我们在处理器与存储设备之间加了一层缓存,基本上解决了cpu与存储设备速度的差别。现在的计算机缓存大体上分为三级,L1级缓存,L2级缓存,L3级缓存,其中L1,L2级缓存属于每个cpu独享,L3级缓存属于多个cpu共享。但是这也引发了一个问题,就是对于共享数据操作的一致性问题。为了解决这个问题,在cpu与缓存之间,我们制定了缓存一致性协议,最常见的就是MESI协议。其中计算机cpu的缓存如下图所示。

解读:计算机处理器与主内存之间添加了一层缓存,为了保证各个处理器对于主内存中数据操作的安全性,引入了缓存一致性协议。各个处理器与主内存中数据的交互必须是建立在缓存一致性协议之上的。

2.理解JMM(java内存模型)

Java虚拟机试图定义一种java内存模型,从而屏蔽掉不同硬件和操作系统的内存访问差异,以实现让java程序在各种平台下都能够达到一致性访问的效果。为此,java定义了下面的java内存模型,如下图。

解读:从图中我们可以大概了解到java内存模型。首先是在每个单独的线程中有一个工作内存,各个工作内存互不干扰。每个线程操作主内存中的数据时,首先是从主内存中拷贝一份到工作内存(read和load操作,后面具体说明),然后对工作内存中的副本进行操作(use和assgin操作,后面具体说明),最后在将工作内存中的数据刷新到主内存中(store和write操作,后面具体说明)。以上就是java内存模型的大概操作流程,下面将详细介绍。

主内存与工作内存的交互:关于主内存和工作内存的交互,在java内存模型定义了8种原子操作,分别是lock,read,load,use,assign,store,write,unlock,下面逐一介绍下。

lock:表示锁定操作,作用于主内存中的变量,表示将一个变量标识线程独占状态,即一个线程标识为lock的变量,其它线程无法访问。

unlock:表示解锁操作,作用于主内存中的变量,表示将一个锁定的变量释放,只有被释放的变量才可被其它的线程访问。

read:表示读取操作,作用于主内存中的变量,表示将一个变量从主内存传输到工作内存。

load:表示载入操作,作用于工作内存中的变量,表示将read操作获取到的变量值存储到工作内存的变量副本之中。

use:表示使用操作,作用于工作内存中的变量,表示将工作内存中一个变量的值传递给执行引擎,每当虚拟机遇到一个需要使用变量值的字节码指令时将会执行这个操作。

assgin:表示赋值操作,作用于工作内存中的变量,表示将一个从执行引擎获取到的值传递给工作内存中的变量,每当虚拟机遇到一个给变量赋值的字节码指令时将会执行这个操作。

store:表示存储操作,作用于工作内存中的变量,表示将一个工作内存中的变量值传递到主内存中,以方便随后的write操作。

write:表示写入操作,作用于主内存中的变量,表示将store操作从工作内存中传递的变量值存储到主内存中的变量中。

除了上述这八种操作之外,java内存模型定义了这八种操作的一些规则。

规则一:不允许一个变量从主内存中读取了,但工作内存不接收。也不允许一个变量从工作内存发起了回写,但主内存不接收。即read与load,store与write不许单独出现。

规则二:一个变量在工作内存中修改之后,必须同步回主内存。即assign操作之后,必须执行store和write操作。

规则三:一个变量在线程中没有执行assgin之前,不允许同步回主内存。

规则四:在一个线程中对变量执行use和store之前,必须先执行了assign和load操作。

规则五:lock和unlock操作规则,一个变量同一时刻只允许同一个线程对其执行lock操作,并且同一个线程可以对其执行多次lock操作。执行了多少次lock操作,释放这个变量的时候也必须执行多少次的unlock操作。

规则六:lock和unlock操作规则,对于执行了lock操作的一个变量,将会清空工作内存中这个变量的值,在执行引擎需要使用到这个变量的值时,需要先执行load或assign初始化这个变量的值。

规则七:lock和unlock操作规则,一个没有被执行lock操作的变量,不予许被执行unlock操作。一个线程对变量执行的lock操作,只能由当前这个线程对其执行unlock操作。

规则八:lock和unlock操作规则,一个变量被执行unlock之前,必须先将此变量同步回主内存,即执行store和write操作。

java多线程之volatile关键字

java多线程基础篇第一篇的更多相关文章

  1. 【Todo】【读书笔记】Java多线程编程指南-设计模式篇

    下了这本书<Java多线程编程指南-设计模式篇>, 还有另一本<JAVA多线程设计模式>,据说内容有重复,结合着看.

  2. 【MM系列】SAP MM模块-基础配置第一篇

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[MM系列]SAP MM模块-基础配置第一篇   ...

  3. [转]Java多线程干货系列—(一)Java多线程基础

    Java多线程干货系列—(一)Java多线程基础 字数7618 阅读1875 评论21 喜欢86 前言 多线程并发编程是Java编程中重要的一块内容,也是面试重点覆盖区域,所以学好多线程并发编程对我们 ...

  4. Java 多线程——基础知识

    java 多线程 目录: Java 多线程——基础知识 Java 多线程 —— synchronized关键字 java 多线程——一个定时调度的例子 java 多线程——quartz 定时调度的例子 ...

  5. Java多线程--基础概念

    Java多线程--基础概念 必须知道的几个概念 同步和异步 同步方法一旦开始,调用者必须等到方法调用返回后,才能执行后续行为:而异步方法调用,一旦开始,方法调用就立即返回,调用者不用等待就可以继续执行 ...

  6. Java多线程基础知识总结

    2016-07-18 15:40:51 Java 多线程基础 1. 线程和进程 1.1 进程的概念 进程是表示资源分配的基本单位,又是调度运行的基本单位.例如,用户运行自己的程序,系统就创建一个进程, ...

  7. Java 多线程基础(五)线程同步

    Java 多线程基础(五)线程同步 当我们使用多个线程访问同一资源的时候,且多个线程中对资源有写的操作,就容易出现线程安全问题. 要解决上述多线程并发访问一个资源的安全性问题,Java中提供了同步机制 ...

  8. JVM学习篇-第一篇

    JVM学习篇-第一篇 JDK( Java Development Kit): ​ Java程序设计语言.Java虚拟机.Java类库三部分统称为JDK,JDK是用于支持Java程序开发的最小环境** ...

  9. Java多线程基础:进程和线程之由来

    转载: Java多线程基础:进程和线程之由来 在前面,已经介绍了Java的基础知识,现在我们来讨论一点稍微难一点的问题:Java并发编程.当然,Java并发编程涉及到很多方面的内容,不是一朝一夕就能够 ...

  10. Java基础16:Java多线程基础最全总结

    Java基础16:Java多线程基础最全总结 Java中的线程 Java之父对线程的定义是: 线程是一个独立执行的调用序列,同一个进程的线程在同一时刻共享一些系统资源(比如文件句柄等)也能访问同一个进 ...

随机推荐

  1. MongoDB语法与现有关系型数据库SQL语法比较

    MongoDB语法            MySql语法 db.test.find({'name':'foobar'})             <==>          select ...

  2. 【spring源码分析】IOC容器初始化(五)

    前言:前几篇文章已经将BeanDefinition的加载过程大致分析完成,接下来继续分析其他过程. AbstractApplicationContext#refresh public void ref ...

  3. Linux:Day9(上) 压缩工具

    压缩.解压缩及归档工具 compress/uncompress:.Z # 现在已经很少在见到了 gzip/gunzip:.gz bzip2/bunzip2:.bz2 xz/unxz:.xz # 目前推 ...

  4. LOJ #6042. 「雅礼集训 2017 Day7」跳蚤王国的宰相

    我可以大喊一声这就是个思博题吗? 首先如果你能快速把握题目的意思后,就会发现题目就是让你求出每个点要成为树的重心至少要嫁接多少边 先说一个显然的结论,重心的答案为\(0\)(废话) 然后我们考虑贪心处 ...

  5. neutron二

    第四篇neutron— 网络实践   一.虚拟机获取 ip:   用 namspace 隔离 DHCP 服务   Neutron 通过 dnsmasq 提供 DHCP 服务,而 dnsmasq 通过 ...

  6. 三十七、小程序页面跳转传参参数值为url时参数丢失

    当参数的值为url的时候,在options中的值没有参数“?”之后字符串被截取.例如:let url="http://baidu.com/?a=1&b=2"wx.navig ...

  7. opendir函数和readdir函数内涵及用法

    工作中遇到奇怪的事,加载增量的时候加载不上.于是开始分析原因,log里边没有任何错误信息,只有加载完成的标志.增量的数据在目录里边是存在的,但是显示的目录大小却不是4096,而是17,不知道为什么.后 ...

  8. Linux centos 推拉、共享、监控的设置的分享

    新建四台虚拟机 打开第一台连接shell更改主机名.网卡 backup 1.主机名网卡配置 [root@jytcentos7.6 ~]# hostnamectl set-hostname backup ...

  9. Oracle查询字符串数据进行排序,以及去重复

    原本的的一张表,填写数据的字段为字符串varchar2类型,然后进行排序的时候,就会出现问题.会默直接默认判断为第一个数字9最大,而不判断整个数字的大小. 所以,就要用到TO_NUMBER函数 sel ...

  10. 解决IOS微信浏览器底部会出现向前向后返回按钮,返回不刷新的问题

    <script type="text/javascript"> //解决IOS返回页面不刷新的问题 var isPageHide = false; window.add ...