多线程学习第三课

LogicCraftPro
• 阅读 735

1、由Volatile实现过程,看计算机多核CPU与内存的交互

多线程学习第三课

多线程学习第三课

相关解释:
a、Volatile修饰的变量,会生成Lock前缀的操作指令,Lock前缀指令会引起处理器缓存回写到内存。
b、当CPU 1修改volatile变量,系统内存中值和其他CPU中的缓存失效是即时性的。
c、红色箭头的嗅探操作:嗅探一个处理器来检测其他处理器打算写内存地址,而这个地址当前处于共享状态,那么正在嗅探的处理器将使它的缓存行无效,在下次访问相同内存地址时,强制执行缓存行填充。(类似一个Listener操作)

关键词:
a、内存屏障:上图中当CPU 1修改本地多级缓存并且要写回内存时,会禁止其他CPU操作内存中的值,这个行为被称为内存屏障。
b、MESI协议: 当一个CPU修改了本地中的多级缓存,会通知其他缓存了这个数据的CPU,其他CPU会把Cache中这份数据的Cache Line置为无效,要读取数据的话,直接去内存中获取,不会再从Cache中获取了。

2、Java内存模型(Java Memory Mode, JMM)

思考:
a、我们都知道,java之所以能在多种操作系统中运行,是因为java“自带了”自己的运行容器:JVM。
b、Java又是支持多线程的,多线程操作访问相同的变量,自然也会有类似上面“多核CPU访问操作同一内存地址且要保证缓存一致性的问题”,所以Java也实现了自己的内存模型。

多线程学习第三课

多线程学习第三课

  线程1和线程2都有主内存中共享变量a的副本,初始时,这3个内存中a的值都为0。线程1中更新a的值为1之后同步到线程2主要涉及2个步骤:
  (1)、线程1把线程工作内存中更新过的a的值刷新到主内存中。
  (2)、线程2到主内存中读取线程1之前已更新过的a变量。

  可以看的出来,JMM和计算机多核CPU在处理“高速缓存和内存”的交互上,是非常相似的。

3、JVM内存中的Java对象

多线程学习第三课

思考:为什么Java对象模型没有看到对象方法?

//对象存储的定义
class oopDesc {
  friend class VMStructs;
  friend class JVMCIVMStructs;
 private:
  //重点  mark word 字段
  volatile markWord _mark;
  //重点  Class 字段
  union _metadata {
    // 对象方法就存在了这里,存放的是指针。为何只需要存放一个指针?因为同一个类的不同实例,包含的方法都是一样,为了节省空间,只需要保存相同的指针就可以了
    Klass*      _klass;
    narrowKlass _compressed_klass;
  } _metadata;

  // There may be ordering constraints on the initialization of fields that
  // make use of the C++ copy/assign incorrect.
  NONCOPYABLE(oopDesc);

 public:
  // Must be trivial; see verifying static assert after the class.
  oopDesc() = default;
  }

4、Mark Word,Java对象的状态标识

多线程学习第三课

由上图可以看出Java对象的五种状态:

多线程学习第三课

5、总结与思考:

a、关于对偏向锁的理解
    偏向锁只是逻辑上的锁,是一个概念。偏向锁干的事就是为了保证线程重入的情况下,可以不触发CAS或Mutex锁。由上面的图可以看出,偏向锁记录了“当前线程指针JavaThread”,之所要记录线程指针,是为了判断类似 if(threadId == currentThreadId), 那么跳过获取锁的过程。总结就是:偏向锁是为了线程重入。
b、为什么Mark Word中会用01 来表示无锁的状态 而不是用00表示无锁的状态?
    待补充......
c、class oopDesc中,volatile markWord _mark,是否表示Mark Word是由Volatile实现的?
点赞
收藏
评论区
推荐文章
Wesley13 Wesley13
3年前
java多线程——并发测试
这是多线程系列第六篇,其他请关注以下:java多线程—线程怎么来的?(https://my.oschina.net/u/1859679/blog/1517807)java多线程内存模型(https://my.oschina.net/u/1859679/blog/1525343)java多线程——volatile
Wesley13 Wesley13
3年前
java多线程——锁
这是多线程系列第四篇,其他请关注以下:java多线程—线程怎么来的?(https://my.oschina.net/u/1859679/blog/1517807)java多线程内存模型(https://my.oschina.net/u/1859679/blog/1525343)java多线程——volatile
梦
4年前
微信小程序new Date()转换时间异常问题
微信小程序苹果手机页面上显示时间异常,安卓机正常问题image(https://imghelloworld.osscnbeijing.aliyuncs.com/imgs/b691e1230e2f15efbd81fe11ef734d4f.png)错误代码vardate'2021030617:00:00'vardateT
浪人 浪人
4年前
一篇文章弄懂Java多线程基础和Java内存模型
文章目录一、多线程的生命周期及五种基本状态二、Java多线程的创建及启动1.继承Thread类,重写该类的run()方法2.通过实现Runnable接口创建线程类3.通过Callable和Future接口创建线程三、Java内存模型概念四、内存间的交互操作五、volatile和synchronized的
Stella981 Stella981
3年前
Opencv中Mat矩阵相乘——点乘、dot、mul运算详解
Opencv中Mat矩阵相乘——点乘、dot、mul运算详解2016年09月02日00:00:36 \牧野(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fme.csdn.net%2Fdcrmg) 阅读数:59593
Stella981 Stella981
3年前
Python实现多进程
Python可以实现多线程,但是因为GlobalInterpreterLock(GIL),Python的多线程只能使用一个CPU内核,即一个时间只有一个线程在运行,多线程只是不同线程之间的切换,对多核CPU来说,就是巨大的浪费。如4核CPU,实际上只利用了一个核,CPU利用率只有25%。要充分利用多核CPU,可以实现Python的多进程。首先,im
Stella981 Stella981
3年前
KVM调整cpu和内存
一.修改kvm虚拟机的配置1、virsheditcentos7找到“memory”和“vcpu”标签,将<namecentos7</name<uuid2220a6d1a36a4fbb8523e078b3dfe795</uuid
Stella981 Stella981
3年前
Github标星5300+,专门为程序员开发文档开源管理系统,我粉了
!(https://oscimg.oschina.net/oscnet/a11909a041dac65b1a36b2ae8b9bcc5c432.jpg)码农那点事儿关注我们,一起学习进步!(https://oscimg.oschina.net/oscnet/f4cce1b7389cb00baaab228e455da78d0
Stella981 Stella981
3年前
Noark入门之线程模型
0x00单线程多进程单线程与单进程多线程的目的都是想尽可能的利用CPU,减少CPU的空闲时间,特别是多核环境,今天咱不做深度解读,跳过...0x01线程池锁最早的一部分游戏服务器是采用线程池的方式来处理玩家的业务请求,以达最大限度的利用多核优势来提高处理业务能力。但线程池同时也带来了并发问题,为了解决同一玩家多个业务请求不被
Wesley13 Wesley13
3年前
Java 多线程:volatile关键字
概念volatile也是多线程的解决方案之一。\\volatile能够保证可见性,但是不能保证原子性。\\它只能作用于变量,不能作用于方法。当一个变量被声明为volatile的时候,任何对该变量的读写都会绕过高速缓存,直接读取主内存的变量的值。如何理解直接读写主内存的值:回到多线程生成的原因(Java内存模型与
LogicCraftPro
LogicCraftPro
Lv1
远书归梦两悠悠,只有空床敌素秋。
文章
5
粉丝
0
获赞
0