美文网首页
Java主流锁体系+ Synchronized底层原理+ AQS

Java主流锁体系+ Synchronized底层原理+ AQS

作者: Minority | 来源:发表于2020-03-19 21:31 被阅读0次

    Java主流锁体系全面认识:

    • 1、乐观锁,悲观锁
    • 2、读锁(共亨锁),写锁(排它锁)
    • 3、自旋锁,非自旋锁
    • 4、无锁,偏向锁,轻量级锁,重量级锁
    • 5、分布式锁
    • 6、区间锁(分段锁)java.util. concurrent ConcurrentHashMap
    • 7、重入锁、非重入锁
    • 8、公平锁、非公平锁
    Java主流锁体系全面认识
    • 如果自旋锁一直拿不到资源,那么会挂起该线程或者抛出异常
    • synchronized是通过Monitor(监视器锁)实现的,监视器对象Monitor通过其monitorenter和moniterexit方法来对代码块进行同步,而这些方法都是依赖的OS底层的Mutex lock(互斥锁)来实现的
    Synchronized锁优化
    • 锁的膨胀升级是不可逆的,因为升级到重量级锁之后,就是Synchronized使用OS底层互斥锁来进行加锁,这个过程直到该线程完成了对临界区的访问。访问完之后就释放锁了,这时候临界区是一个无锁的状态,所以整个过程不可逆,是一个循环的过程(一个周期)。
    • Synchronized是隐式锁,其是基于JVM的内置锁,加锁和解锁的过程不需要我们在代码中人为控制,JVM会自动加锁和解锁。ReentrantLock是显式锁,通过AQS实现,加锁和解锁的过程需要手动控制。AQS(AbstractQueuedSynchronizer)
    • Synchronized和所有实现了Lock接口的都是悲观锁

    Synchronized底层优化:

    面试题:实例对象是怎么存储的?

    • 对象的实例存储在堆中
    • 对象的引用存储在栈中
    • 对象的元数据存储在方法区(元空间/永久代)




    Q:为什么不直接上重量级锁?
    A:上重量级锁会涉及到线程的上下文切换,会涉及到OS用户态到内核态的切换,非常消耗资源

    线程的上下文切换耗费资源:

    • JVM是运行在OS上面的,他无法操作OS,其是运行在用户态的程序,所以他要向OS请求切换到内核态,让CPU创建新的时间片来处理JVM的新线程。CPU运行时的一些中间变量都是保存在寄存器的,所以切换线程时,老的线程的一些信息就需要回写到内存中线程对应的进程中的PCB中。然后CPU加载新线程,新线程运行完,再从PCB的阻塞队列唤醒老的线程,CPU重新加载其Context,然后再运行老线程。
    • 现代os都将线程作为最小调度单位,进程作为资源分配的最小单位,所以说单核CPU线程之前是并发而不是并行。

    AQS原理:

    AQS原理

    知识点:
    ReentrantLock是可重入锁,底层是有AQS实现,AQS有四个重要的属性:head、tail、state、exclusiveOwnerThread

    • head:CLH的队头
    • tail:CLH的队尾
    • state:当前可重入锁加锁的次数
    • exclusiveOwnerThread:当前获得锁的线程

    使用CAS算法来循环判断state是否为0:

    • 如果为0则获得锁
    • 如果不为0则加入CLH队列
    • 如果state不为0且CLH队列满,则报错

    注意:加入CLH队列的顺序通过指定公平锁和非公平锁来决定,非公平锁会先使用CAS看一下state是否为0,如果是的话就获得锁,而不是先进入CLH进行排队

    • 注意:ArrayBlockQueue是一个条件队列

    参考:https://www.bilibili.com/video/av77009927?p=1

    相关文章

      网友评论

          本文标题:Java主流锁体系+ Synchronized底层原理+ AQS

          本文链接:https://www.haomeiwen.com/subject/qojryhtx.html