当前位置: 首页 > news >正文

Java线程---锁机制

Syschronized同步锁

同一时刻,只有一个线程能持有这把锁,保证代码的线程安全

Syschronized关键字的用法

1.修饰实例方法---->this为当前方法的调用对象

  • 对加锁的代码块限制了线程访问,并不影响其他线程访问没加锁的代码块

  • 子类若重写父类syschronized修饰的方法,线程是否安全以子类重写的为准

  • 定义接口方法时,不能使用syschronized关键字

  • 构造方法不能使用syschronized关键字,但可以使用syschronized代码块来进行同步。

  • 离开syschronized代码块后,该线程所持有的锁,会自动释放。

2.修饰静态方法---->Class对象

3.修饰代码块---->某个指定的Java对象

Syschronized实现原理

Java5以前---------Syschronized同步锁在加锁和解锁过程中,依赖于操作系统互斥锁(Mutex LOCK)所实现的锁。属于重量级锁。

Java6之后---------采用monitor机制和JVM指令实现

  • Monitor机制

每个java对象都可成为Monitor监视器,分为三部分

Wait Set线程等待区---等待唤醒,重新尝试获取Monitor

Entry List 线程阻塞区---等待锁释放

Owner 线程拥有者-----执行同步代码块或者同步方法中的代码

  • JVM指令

    • Syschronized修饰方法,方法常量池添加名为ACC_Syschronized的标志,调用方法时,需要先获取当前this对象的监视器才能继续,方法执行完后释放监视器锁

    • Syschronized修饰代码块,通过monitorenter和monitorexit两个指令实现

    monitorenter指令插入到同步代码块的开始位置,尝试获取Monitor监视器的所有权;monitorexit指令插入到方法结束处或异常处,JVM保证每个monitorenter必须有对应的monitorexit。

Syschronized底层实现✔

Syschronized保证线程安全,保证原子性

  • 通过monitorenter/monitorexit指令实现同步

  • 通过对象内部---监视器(monitor)来实现的

监视器(monitor)

监视器-------充当锁的的对象对当前竞争锁的所有线程进行管理

锁优化

  • 自旋锁:线程等待一段时间,不会立即挂起,看持有锁的线程是否很快释放锁

  • 适应性自旋锁:自旋次数不固定,根据前一次在同一个锁上的自选时间及锁的拥有者状态决定

  • 锁粗化:将一系列连续加锁、解锁操作,合并为一个较大范围的加锁解锁操作

  • 锁消除:JVM检测到不可能存在共享数据竞争时,会对同步锁进行锁消除

锁升级/锁膨胀!!!

偏向锁------>轻量级锁------>重量级锁

偏向锁:

加锁的代码从始至终只有一个线程在调用,如果发现有多于一个线程交替执行同步块情况,再升级成轻量级锁。

轻量级锁:

不支持"并发",出现并发情况即多个线程同一时间访问同一把锁的情况,就会升级为重量级锁

  • 轻量级锁加锁:对象锁处于无锁状态,虚拟机在线程的帧栈中建立Local Record(锁记录)存储锁对象目前的Mark Word,将对象的Mark Word中的指向栈中锁记录的指针更新为Local Record指针,并将Local Record里的owner指针指向对象的Mark Word。

  • 轻量级锁解锁:通过CAS指令,将线程中复制的Displaced Mark Word对象替换当前的Mark Word。

(获取锁采用自旋方式,通过循环获取锁避免线程阻塞)

重量级锁:

依赖于操作系统互斥锁所实现的锁,需要从用户态转换为内核态,切换成本高。

ReentrantLock锁

ReentrantLock和Syschronized一样,都是可重入锁,即一个线程可以多次获取同一个锁。

ReentrantLock与Syschronized的区别

  • 锁实现机制:ReentrantLock基于AQS框架;Syschronized基于监视器Monitor和JVM指令实现。

  • 获取锁方式:ReentrantLock可通过tryLock()尝试获取锁,更灵活且在失败的时候不会导致死锁;Syschronized则是线程抢占模型

  • 释放锁方式:ReentrantLock必须显示通过unlock()释放锁,Syschronized可自动释放锁

  • 锁的类型:ReentrantLock支持公平锁和非公平锁;Syschronized只支持非公平锁。

ReentrantLock内部结构

三个内部类

  • Sync

  • NonfairSync继承Sync类:非公平策略获取锁(默认)

  • FairSync继承Sync类:公平策略获取锁,当资源空闲会判断Sync队列中是否有等待时间更长的线程,如存在,则入队尾。

通过ReentrantLock(boolean)构造函数,传递参数指定采取策略 true---公平策略 false---非公平策略


http://www.mrgr.cn/news/30103.html

相关文章:

  • 【记录一下】jenkins的安装与部署教程
  • 从北大张泽民院士团队的研究成果中寻找医学AI未来的发展方向|个人观点·24-09-19
  • 【日记】书荒了(337 字)
  • 耐压110V茂睿芯MK9019可以向下兼容MK9016
  • 电脑怎么设置开机密码?3个方法迅速搞定!
  • 大华主动注册协议接入SVMSPro平台
  • 【数据结构】排序算法---计数排序
  • python多进程程序设计 之三
  • 最优化理论与自动驾驶(十一):基于iLQR的自动驾驶轨迹跟踪算法(c++和python版本)
  • 如何将MySQL卸载干净(win11)
  • C++学习, 异常处理
  • Docker常用命令总结
  • Java线程池运行流程、配置参数及线程池类型
  • MATLAB系列08:输入/输入函数
  • 江协科技STM32学习- P13 TIM定时器中断
  • 探秘Python中的链表:从零开始的奇妙之旅
  • JAVA惊喜连连无限可能沉浸式盲盒商城系统小程序源码
  • 代码随想录 -- 二叉树 -- 删除二叉搜索树中的节点
  • 工单管理软件的优势有哪些?企业如何选择?
  • 【每日一诗】【诗词创作】【诗】《雨前秋夜》