Java 各种锁总结

Java 各种锁总结

1、公平锁非公平锁

公平锁:是指多个线程按照申请锁的顺序来获取锁,类似排队打饭,先来后到。

非公平锁:是指多个线程获取锁的顺序并不是按照申请锁的顺序,有可能后申请的线程比现申请的线程
优先获取锁,在高并发的情况下,有可能会造成优先级反转或者饥饿现象

在这里插入图片描述

并发包中的 ReentrantLock 的创建可以指定构造函数 的 boolean类型来得到公平锁或者非公平锁,默认
是非公平锁!

公平锁:就是很公平,在并发环境中,每个线程在获取到锁时会先查看此锁维护的等待队列,如果为
空,或者当前线程是等待队列的第一个,就占有锁,否则就会加入到等待队列中,以后会按照FIFO的规
则从队列中取到自己。

非公平锁:非公平锁比较粗鲁,上来就直接尝试占有锁,如果尝试失败,就会采用类似公平锁那种方
式。

Java ReentrantLock 而言,通过构造函数指定该锁是否是公平锁,默认是非公平锁。非公平锁的优点在
于吞吐量比公平锁大

对于Synchronized而言,也是一种非公平锁

2、可重入锁

可重入锁(也叫递归锁)

指的是同一线程外层函数获得锁之后,内层递归函数仍然能获取该锁的代码,在同一个线程在外层方法
获取锁的时候,在进入内层方法会自动获取锁。

也就是说,线程可以进入任何一个它已经拥有的锁,所同步着的代码块。 好比家里进入大门之后,就可
以进入里面的房间了;

ReentrantLock、Synchronized 就是一个典型的可重入锁;

可重入锁最大的作用就是避免死锁
测试一:Synchronized

在这里插入图片描述在这里插入图片描述

测试二:ReentrantLock
在这里插入图片描述
在这里插入图片描述

3、自旋锁

自旋锁(spinlock)

是指尝试获取锁的线程不会立即阻塞,而是采用循环的方式去尝试获取锁,这样的好处是减少线程上下
文切换的消耗,缺点是循环会消耗CPU。
在这里插入图片描述
测试代码:
在这里插入图片描述
在这里插入图片描述

4.乐观锁

乐观锁顾名思义就是一种乐观的思想,认为读数据时没有别的线程进行过修改,所以不会上锁,写数据时判断当前与期望的值是否相同,如果相同进行更新(更新期间是要枷锁的,为了保证原子性)

5.悲观锁

悲观锁顾名思义就是一种悲观的思想,每次拿数据都会悲观的认为其他线程修改了数据,所以每次读写时都会上锁,其他线程想要读写这个数据时,就会被该线程阻塞 ,直到这个线程释放锁

6.读写锁

读写锁使一种技术,通过ReentrantReadWriteLock类来实现的,为了提高性能,Java提供了读写锁,读的地方使用 读锁,写的地方使用写锁,在没有写锁的情况下,读锁是无阻塞的,多个读锁不互斥,读锁与写锁互斥,这是由jvm来控制的

读锁: 允许线程获取读锁,同时访问一个资源

写锁: 允许一个线程获取 写锁,不允许 同时访问一个资源

7.共享锁

共享锁是一种思想,可以多个线程获取读锁,以共享的方式持有锁,和乐观锁还有读写锁同义

8.独占锁

独占锁是一种思想,只能有一个线程获取锁,以独有的方式持有锁,悲观锁和互斥锁同义

9.重量级锁

synchronized 就是重量级锁,为了优化重量级锁,引入了轻量级锁和偏向锁

10.轻量级锁

jdk6是加入的一种锁的优化机制,轻量级锁是在没有多线程竞争的情况下使用的CAS操作去消除同步使用的互斥量

    上面理解起来很吃力,解析一下,首先是没有竞争,也就是说是单线程 ,两条以上线程,轻量级锁不会生效

11.偏向锁

偏向锁 是JDK6时加入的一种锁优化机制: 在无竞争的情况下把整个同步都消除掉,连CAS操作都不去做了。偏是指偏心,它的意思是这个锁会偏向于第一个获得它的线程,如果在接下来的执行过程中,该锁一直没有被其他的线程获取,则持有偏向锁的线程将永远不需要再进行同步。持有偏向锁的线程以后每次进入这个锁相关的同步块时,虚拟机都可以不再进行任何同步操作.

12.分段锁

是一种机制,是不是想到了ConcurrentHashMap了,默认情况下ConcurrentHashMap被细分为16个段(Segment)每次上锁只是锁的每个segment. segment通过继承ReentrntLock来进行加锁,只要保证每个segment是线程安全的,是不是就保证了全局的线程安全.

13.互斥锁

互斥锁和悲观锁还有独占锁同义,某个资源,只能被一个线程访问,其他线程不能访问.

例如上文提到的读写锁中的写锁,写与写之间是互斥的,写与读之间也是互斥的

14.同步锁

与互斥锁同义,字并发执行多个线程时,在同一时间只允许一个线程访问共享数据 synchronized

15.死锁

死锁是一种现象: 如线程A持有资源x,线程B持有资源y,线程A等待线程B释放资源
y,线程B等待线程A释放资源x,两个线程都不释放自己持有的资源,则两个线程都获
取不到对方的资源,就会造成死锁。
Java中的死锁不能自行打破,所以线程死锁后,线程不能进行响应。所以一定要注意
程序的并发场景,避免造成死锁。

  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值