继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

Java并发

慕神8447489
关注TA
已关注
手记 1134
粉丝 172
获赞 955

并发的挑战

上下文切换: 是消耗资源的操作,进入内核态需要

资源限制 :  I/O 数据库,cpu核数

死锁 :等待不到需要的资源

volatile

内存语义

当写一个volatile变量时,JMM会把该线程对应的本地内存中的共享变量值刷新到主内存中。当读一个volatile变量时,JMM会把该线程对应的本地内存置为无效,线程接下来将从主内存中读取共享变量

硬件实现

使用硬件指令当前缓存行刷入主内存

是其他缓存中此变量的缓存行无效

使得读操作需要重新从主内存加载此变量

适用场景

只有一个线程对volatile变量写

Synchronized

锁的对象

Java中的每一个对象都可以作为锁。

对于同步方法,锁是当前实例对象。

对于静态同步方法,锁是当前对象的Class对象。

对于同步方法块,锁是Synchonized括号里配置的对象

实现

同步方法

使用 ACC_SYNCHRONIZED 标记符隐示的实现,原理是通过方法调用指令检查该方法在常量池中是否包含 ACC_SYNCHRONIZED 标记符,JVM 要求线程在调用之前请求锁

同步代码块

webp

JVM通过monitorenter和monitorexist指令实现同步锁的获取和释放功能

monitorenter指令是在编译后插入到同步代码块的开始位置

monitorexit指令是插入到方法结束处和异常处

JVM要保证每个monitorenter必须有对应的monitorexit与之配对

任何对象都有一个monitor与之关联,当且一个monitor被持有后,它将处于锁定状态

线程执行monitorenter指令时,将会尝试获取对象所对应的monitor的所有权,即尝试获得对象的锁

线程执行monitorexit指令时,将会将进入次数-1直到变成0时释放监视器

同一时刻只有一个线程能够成功,其它失败的线程会被阻塞,并放入到同步队列中,进入BLOCKED状态

虚拟机做的锁优化

1.锁消除,消除无谓的锁

2.锁粗化,合并太小粒度的加锁

3.锁自旋,自适应自旋

4.锁膨胀

锁膨胀

Java对象头

webp

偏向锁

为了在无多线程竞争的情况下尽量减少不必要的轻量级锁执行路径

,而偏向锁则是在只有一个线程执行同步块时进一步提高性能


webp


轻量级锁

目的是没有多线程竞争的前提下,减少传统的重量级锁

轻量级锁是为了在线程交替执行同步块时提高性能


webp


重量级锁实现

Monitor Record结构

MonitorRecord(统一简称MR)是Java线程私有的数据结构,每一个线程都有一个可用MR列表,同时还有一个全局的可用列表

一个被锁住的对象都会和一个MR关联(对象头的MarkWord中的LockWord指向MR的起始地址)

MR中有一个Owner字段存放拥有该锁的线程的唯一标识,表示该锁被这个线程占用

webp

Monitor Record工作机理


webp

线程如果获得监视锁成功,将成为该监视锁对象的拥有者



作者:山鱿鱼
链接:https://www.jianshu.com/p/bdbd14e709da


打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP