zoukankan      html  css  js  c++  java
  • 并发编程-synchronized

    synchronized锁什么?

     锁对象,可能包括:this, 临界资源对象,class类对象

    锁的底层实现

    同步代码块基于monitor enter和monitor exit指令实现同步,

    同步方法基于读取运行时常量池中方法的ACC_SYNCHRONIZED标志来隐式实现。

    对象内存的组成

    对象头:存储对象的hashcode锁信息GC信息类型指针

    实例变量

    填充数据:虚拟机要求对象的起始地址必须是8字节的整数倍。填充数据不是必须存在的,仅仅为了字节对齐。

    执行过程

    当执行synchronized同步方法或同步代码块时,会在对象头中记录锁标记,锁标记指向monitor对象的起始地址。

    monotor对象:每个对象都存在一个monitor与之关联,monitor可以与对象一起创建销毁或当线程试图获取对象锁时自动生成。当monitor对象被某个线程持有后,便处于锁定状态

    monitor是由ObjectMonotor实现的。ObjectMonitor中包括:_owner标记,两个队列,_waitSet\_entryList

    所线程并发访问同一个同步代码时,首先进入_entryList, 当线程获取锁标记后,_owner记录此线程,且在monitor中的计数器执行+1操作代表锁定。其他线程在_entryList中继续阻塞。

    如果执行线程调用wait方法,则monitor中的计数器置为0,_owner置为null,代表放弃锁,执行线程进入waitset中阻塞。

    如果执行线程调用notify otifyAll,_waitset中的线程被唤醒,进入_entryList中阻塞,等待获取锁标记。

    如果执行线程的同步代码执行结束,会释放锁标记,monitor中的计数器置为0,_owner置为null

     

    在jdk1.6之前,synchronized使用的是重量锁。由于重量锁引起的线程阻塞唤醒开销太大,于是对此做了优化。

    先提供偏向锁,如果不满足的时候,升级为轻量级锁,再不满足,升级为重量级锁。

    锁只能升级,不能降级。

    偏向锁 : 它会偏向第一个访问锁的线程,如果不存在多线程竞争,是不需要触发同步的,这种情况下就会给线程加一个偏向锁。如果存在其他线程竞争,那么持有偏向锁的线程会被挂起,锁升级为轻量级锁。

    它通过消除资源无竞争情况下的同步原语,进一步提高了程序的性能。

    轻量级锁:先不把线程阻塞挂起前,先让线程空循环等待。轻量级锁适用于同步代码执行很快的场景,这样线程原地等待很短时间就能够获得锁了,而不需阻塞唤醒线程。

     

  • 相关阅读:
    L1-009. N个数求和
    L1-008. 求整数段和
    L1-007. 念数字
    L1-006. 连续因子
    L1-005. 考试座位号
    L1-003. 个位数统计
    mtk preloader学习笔记
    android kernel启动学习笔记
    android MTK平台编译UBOOT学习笔记
    dota2输入法无候选框?
  • 原文地址:https://www.cnblogs.com/yintingting/p/11424306.html
Copyright © 2011-2022 走看看