java 并发 唯一,Java并发

并发的挑战

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

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

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

volatile

内存语义

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

硬件实现

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

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

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

适用场景

只有一个线程对volatile变量写

Synchronized

锁的对象

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

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

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

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

实现

同步方法

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

同步代码块

bdbd14e709da

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

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

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

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

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

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

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

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

虚拟机做的锁优化

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

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

3.锁自旋,自适应自旋

4.锁膨胀

锁膨胀

Java对象头

bdbd14e709da

偏向锁

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

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

bdbd14e709da

轻量级锁

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

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

bdbd14e709da

重量级锁实现

Monitor Record结构

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

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

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

bdbd14e709da

Monitor Record工作机理

bdbd14e709da

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

在任一时刻,监视器对象只属于一个活动线程(Owner)

拥有者可以调用wait方法自动释放监视锁,进入等待状态

AQS

原子操作

bdbd14e709da

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值