编程语言
首页 > 编程语言> > 朋友问,你对Java锁理解的那么好,为什么不分享给大家?

朋友问,你对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。

分段锁

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

互斥锁

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

同步锁

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

死锁

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

锁粗化和锁消除

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

标签:加锁,Java,竞争,互斥,理解,线程,公平,分享,轻量级
来源: https://www.cnblogs.com/zhncnblogs/p/16423256.html