• 浅谈 synchronized 锁机制原理 与 Lock 锁机制


    前言

    线程安全是并发编程中的重要关注点,造成线程安全问题的主要原因有两点,一是存在共享数据(也称临界资源),二是存在多条线程共同操作共享数据。

    因此为了解决这个问题,我们可能需要这样一个方案,当存在多个线程操作共享数据时,需要保证同一时刻有且只有一个线程在操作共享数据,其他线程必须等到该线程处理完数据后再进行,这种方式叫互斥锁,即能达到互斥访问目的的锁,也就是说当一个共享数据被当前正在访问的线程加上互斥锁后,在同一个时刻,其他线程只能处于等待的状态,直到当前线程处理完毕释放该锁。

     

    一、synchronized锁机制

    1、synchronized 的作用:

    synchronized 通过当前线程持有对象锁,从而拥有访问权限,而其他没有持有当前对象锁的线程无法拥有访问权限,保证在同一时刻,只有一个线程可以执行某个方法或者某个代码块,从而保证线程安全。

    synchronized 可以保证线程的可见性,synchronized 属于隐式锁,锁的持有与释放都是隐式的,我们无需干预。synchronized最主要的三种应用方式:

    • 修饰实例方法:作用于当前实例加锁,进入同步代码前要获得当前实例的锁

    • 修饰静态方法:作用于当前类对象加锁,进入同步代码前要获得当前类对象的锁

    • 修饰代码块:指定加锁对象,进入同步代码库前要获得给定对象的锁

    2、synchronized 底层语义原理:

    synchronized 锁机制在 Java 虚拟机中的同步是基于进入和退出监视器锁对象 monitor 实现的(无论是显示同步还是隐式同步都是如此),每个对象的对象头都关联着一个 monitor 对象,当一个 monitor 被某个线程持有后,它便处于锁定状态。在 HotSpot 虚拟机中,monitor 是由 ObjectMonitor 实现的,每个等待锁的线程都会被封装成 ObjectWaiter 对象,ObjectMonitor 中有两个集合,_WaitSet 和 _EntryList,用来保存 ObjectWaiter 对象列表 ,owner 区域指向持有 ObjectMonitor 对象的线程。

    当多个线程同时访问一段同步代码时,首先会进入 _EntryList 集合尝试获取 moniter,当线程获取到对象的 monitor 后进入 _Owner 区域并把 _owner 变量设置为当前线程,同时 monitor 中的计数器 count 加1;若线程调用 wait() 方法,将释放当前持有的 monitor,count自减1,owner 变量恢复为 null,同时该线程进入 _WaitSet 集合中等待被唤醒。若当前线程执行完毕也将释放 monitor 并复位变量的值,以便其他线程获取 monitor。如下图所示:

    • _EntryList:存储处于 Blocked 状态的 ObjectWaiter 对象列表。

    • _WaitSet:存储处于 wait 状态的 ObjectWaiter 对象列表。

     

  • 相关阅读:
    运算符重载
    7.Spring — 声明式事务
    【字节码⻆度看synchronize】三种应用方式、Monitor类、monitorenter、monitorexit_JUC15
    C++【C++11】
    [附源码]计算机毕业设计JAVAjapm青篮汇篮球培训系统
    Java精进-20分钟学会mybatis使用
    java版Spring Cloud之Spark 离线开发框架设计与实现
    数据库MySQL(五):多表查询
    双十一什么蓝牙耳机好?盘点性价比高蓝牙耳机推荐
    亚马逊筋膜枪UL1647测试报告流程介绍
  • 原文地址:https://blog.csdn.net/m0_72885838/article/details/126487717