深入理解Java虚拟机读书笔记(四)

四、高效并发

1. Java内存模型与线程

1.1 概述

计算机大部分时间都花磁盘I/O,网络通讯,数据库访问,CPU大部分时间都在等待其他资源的状态,因此需要同时处理多个任务

另一个并发应用场景,就是服务端同时对多个客户端提供服务

1.2 硬件效率与一致性

CPU运算速度比访问内存速度快得多,因此加上了高速缓存,将数据复制到缓存中,CPU从缓存中读取数据高速运算,运算结束后把结果从缓存同步到主内存。这样可以解决处理器和内存速度矛盾,但是会引入缓存一致性问题。多处理器访问同一主内存区域,各自缓存可能不一致。因此各处理器访问内存需要遵循协议:MSI MESI MOSI Synapse Firefly Dragon Protocol等

处理器对代码可能进行乱序执行优化。相应的,虚拟机即时编译器也有类似的指令重排序优化

1.3 Java内存模型

主内存与工作内存

所有共享的变量在主内存中,每个线程有自己的工作内存,线程对变量的操作都必须在工作内存中进行,而不能直接操作主内存,线程间变量传递需要主内存

内存间交互操作

八个指令:

  • lock:作用于主内存,把主内存变量标识为线程独占

  • unlock:作用于主内存,把主内存变量解锁,解锁后其他线程才能锁定

  • read:作用于主内存,把变量的值从主内存传到工作内存

  • load:作用于工作内存,把主内存得到的值,放到工作内存变量副本

  • use:作用于工作内存,虚拟机遇到需要使用变量的字节码指令时会执行。把变量的值传给执行引擎

  • assign:作用于工作内存,虚拟机遇到给变量赋值的字节码指令时会执行。把从执行引擎接收到的值赋值给工作内存的变量

  • store:作用于工作内存,把工作内存中的变量的值传到主内存

  • write:作用于主内存,把从工作变量中得到的值放到主内存变量中

注意:

  • read、load与store、write必须按先后顺序执行,但是中间可以穿插其他操作

  • read、load与store、write必须成对出现,即不允许从一边读了但另一边不接受

  • assign了就一定要同步回主内存

  • 没有assign过不允许同步回主内存

  • 不允许工作内存中直接使用未初始化(assign/load)的变量,use store操作前,必须执行过了assign和load

  • lock可以执行多次,但需要解锁同样次数

  • 执行lock前,会清空工作内存中此变量的值。执行引擎使用此变量前,需要先assign或load重新初始化

  • 没有lock不允许unlock

  • unlock前必须把变量同步回主内存,即执行store、write

对于volatile型变量规则

volatile可以保证变量对所有线程可见,但并不是绝对线程安全,多写场景下仍然有并发问题,因为写的操作不是原子的。volatile适合一写多读场景

volatile另一个语义是禁止指令重排序优化

volatile的读效率与正常变量差不多,写效率慢一写,因为需要插入内存屏障

对于long和double型变量规则

虽然虚拟机规范中允许把64位数据分为两次32位操作,但具体实现时,仍然会把64位数据作为原子操作

原子性、可见性、有序性

原子性:6个基本操作是原子性的,如果不能满足需要,可以用lock、unlock指令,对应字节码指令monitorenter、monitorexit

可见性:一个线程修改了变量的值,其他线程能够立即知道修改的值。volatile、final、synchronized三个关键字都能够保证变量可见性。被final修饰的字段在构造器中一旦被初始化完成,并且构造器没有把this的引用传递出去,那么其他线程就能看见final字段的值。synchronized的可见性指的是,unlock操作前,必须把变量从工作内存同步到主内存

有序性:volatile可以禁止指令重排序,synchronized是可以保证同一时刻只有一个线程访问

先行发生原则

天然有先后顺序,无需进行同步控制

1.4 Java与线程

一对一,映射到轻量级进程

调度方法:抢占式调度

线程状态转换

2. 线程安全与锁优化

2.1 线程安全

多个线程访问一个对象,不用考虑线程调度和交替执行,不用额外同步,调用这个对象都可以获取到正确的结果

Java中的线程安全

  • 不可变:如final修饰,比如String、Number的部分子类(Integer、Long等),注意,AtomicInteger等不属于

  • 绝对线程安全:没有

  • 相对线程安全:线程安全的容器,比如Vector、CurrentHashMap,Collections中的SynchronizedCollection()方法包装的集合

  • 线程兼容:调用端进行同步,可以保证多线程安全使用,比如HashMap

  • 线程对立:很少,已废弃

实现方法

  • 互斥同步:即加锁,synchronized、Lock

  • 非阻塞同步:无锁,CAS

  • 无同步方案:线程本地存储,如ThreadLocal

2.2 锁优化

自旋锁与自适应自旋

忙循环,CPU不让出执行权

自旋一定次数还没有获取到锁,可以省略自旋

锁消除

基于逃逸分析,如果不会被其他线程访问到,可以消除同步措施

锁粗化

循环加锁扩展到外部只加一次锁

轻量级锁

对象头包含两部分信息:1.对象自身运行时数据,比如哈希码,分代年龄,64位OS中长度是64bit;2.方法区类型数据指针,如果是数组,则还有数组长度

[图片上传失败...(image-79696f-1651548783059)]

线程中的LockRecord空间,可以存储对象markword的拷贝,即Displaced Mark Word。加锁的时候,CAS地更新对象markword为指向LockRecord的指针,如果更新成功,则标志位置为了00,加锁成功,没有则加锁失败。解锁过程就是把指针更新回Displaced Mark Word,如果更新成功则解锁成功,失败则说明有其他线程尝试获取过锁,要释放锁的时候,唤醒被挂起的线程。如果有2个以上线程竞争,则升级为重量级锁,标志位为10.

偏向锁

对一个无锁对象,把线程id记录到markword中,再有一个线程来获取锁,标志位恢复01(无锁)或00(轻量级锁)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,783评论 5 472
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,396评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 147,834评论 0 333
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,036评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,035评论 5 362
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,242评论 1 278
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,727评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,376评论 0 255
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,508评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,415评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,463评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,140评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,734评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,809评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,028评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,521评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,119评论 2 341

推荐阅读更多精彩内容