• 朋友问,你对Java锁理解的那么好,为什么不分享给大家?


    转载自:https://baijiahao.baidu.com/s?id=1697365218983521838&wfr=spider&for=pc

    我们在工作中,不知你是否留意java的一些锁,什么乐观锁、悲观锁、自旋锁、可重入锁、读写锁、公平锁、非公平锁、共享锁、独占锁、重量级锁、轻量级锁、偏向锁、分段锁、互斥锁、同步锁、死锁、以及锁粗化和锁消除。

    乐观锁

    是一种乐观思想,假设当前业务读多写少,遇到并发写的概率比较低,读数据时候认为别的线程不会对数据进行修改,所以没有上锁。写数据时候,判断当前与期望的值是否相同,如果相同则进行更新,java中的乐观锁主要用到cas的比较并替换,比较预期值和当前值是否一样,一样则更新,否则进行cas操作。

    悲观锁

    悲观锁是一种悲观思想,即认为写多读少,遇到并发写的可能性高,每次进行业务修改的时候,都会认为其它业务操作会对数据进行修改,所以每次读写数据的时候就会上锁。

    自旋锁

    自旋锁属于一种技术,为了让线程等待,只需让线程来执行一个循环,但不放弃处理器的执行时间,看看持有锁的线程是否很快就会释放锁。

    可重入锁

    可重入锁也是一种技术,任意线程在获取锁之后,能够再次获取锁,而不会被锁所排斥。

    读写锁

    这个很好理解,当一个读线程来的时候,会首先判断这个锁是否是被写锁持有,如果当前线程也不是带有写锁的线程,那么就会返回负一,即获取锁失败,当前线程会被放入等待队列里面等待。如果当前线程是写锁或者锁没被其它线程所持有,那么当前读就可以获取读锁。

    公平锁和非公平锁

    何谓公平,就是线程来的时候公平对待,严格的按照顺序。

    非公平就不按照锁的顺序了,有可能后申请的锁比先进入的锁更先获取锁,在高并发情况下。

    共享锁

    又称读锁,若事务T对数据对象A加上S锁,则事务T可以读A但不能修改A,其他事务只能再对A加S锁,而不能加X锁,直到T释放A上的S锁。这保证了其他事务可以读A,但在T释放A上的S锁之前不能对A做任何修改。

    独占锁

    多占锁顾名思义,每次只有一个线程持有锁。

    重量级锁、轻量级锁偏向锁

    如果实际上没有锁竞争,那么竞争的锁就会一直等待,我们引入轻量级锁来降低线程之间切换的成本。

    在JDK 1.6之前,监视器锁可以认为直接对应底层操作系统中的互斥量(mutex)。这种同步方式的成本非常高,包括系统调用引起的内核态与用户态切换、线程阻塞造成的线程切换等。因此,后来称这种锁为“重量级锁”。

    在没有实际竞争的情况下,还能够针对部分场景继续优化。如果不仅仅没有实际竞争,自始至终,使用锁的线程都只有一个,那么,维护轻量级锁都是浪费的。偏向锁的目标是,减少无竞争且只有一个线程使用锁的情况下,使用轻量级锁产生的性能消耗。轻量级锁每次申请、释放锁都至少需要一次CAS,但偏向锁只有初始化时需要一次CAS。

    分段锁

    是把一个激烈竞争的锁分为多个锁,这多个锁存在激烈的竞争。

    互斥锁

    在编程中,之所以存在互斥锁是因为为了保证数据的完整性,使得每个对象都有一个互斥锁的标记。

    同步锁

    同步锁是为了保证每个线程都能正常执行原子不可更改操作。

    死锁

    死锁是指两个线程互相持有对方的锁,而彼此不释放。

    锁粗化和锁消除

    锁消除是多此一举的加锁,代码片本事不会因为资源共享而发生冲突,而锁粗化顾名思义是增大加锁范围,在某一些情况下,我们希望把多次加锁合并成一次,避免反复的加锁降低性能,锁的申请和释放本身会带来性能损耗

  • 相关阅读:
    Linux下安装mysql(1)(CentOS)
    shell 运算符
    shell $*与$@的区别
    XMind破解
    在CentOS系统上将deb包转换为rpm包
    一次与流氓软件的斗争,浏览器主页被锁定
    dropzone上传文件
    KindEditor4.1.10,支持粘贴图片
    bootstrap paginator使用简述
    sendkeys && appactivate
  • 原文地址:https://www.cnblogs.com/zhncnblogs/p/16423256.html
Copyright © 2020-2023  润新知