几种锁的说明

在平时开发中,存在很多种锁,今天对几种锁都进行简单的说明一下。它们分别是悲观锁、乐观锁、可重入锁、读写锁、CAS(无所机制)、自旋锁

今天比较深入讨论的是前几种锁的定义,关于CAS和自旋锁,之后可能详细学习后再进行记录。

悲观锁和乐观锁

1、悲观锁,当使用悲观锁的时候,资源被一个操作者操作的时候,其它操作者都需要等待。具有独占性和排它性,在资源被处理的过程之中,一直处于锁定的状态。也可以说,其采用的是“先锁定在访问”的保守侧率。

举例,更新数据库,使用for update 就是典型的悲观锁,在更新之前,锁定数据,其它线程无法对资源进行操作。(使用其它文档的图)

所以,使用了悲观锁,每次只能有一个线程对资源进行操作,其它的线程全部阻塞,效率低下。(使用 select…for update 锁数据,需要注意锁的级别,MySQL InnoDB 默认行级锁。行级锁都是基于索引的,如果一条 SQL 语句用不到索引是不会使用行级锁的,会使用表级锁把整张表锁住,这点需要注意。)

2、乐观锁,乐观锁使用版本号对数据进行控制,当一个线程对数据进行修改的时候,伴随着版本号会进行修改,其它线程想修改数据的时候,就查询不到版本号了。适用于度多、写少的场景。(CAS就是乐观锁的体现)

从上述伪代码可知,当一个线程进行更新后,其它线程就找不到version=1的数据了,update语句也就失效了,这里是直接告诉程序失效,让其可以重新尝试,并不是进行阻塞。

可重入锁

可重入锁其实就是锁是集成的,也就是线程获得过某个锁,再次获取这个锁的时候,是不会出现死锁的情况的。

java中synchronized、ReentrantLock 都是可重入锁。废话不多上代码:

上面的代码可以展示,在m1方法获取到的是Test01的类锁,在没释放之前,m2方法也获取了Test01的类锁,但是没有出现死锁的问题,这就是可重入锁。

这篇文档,讲的很棒,例子很生动,大家可以看看,传送门

读写锁

读写锁是Lock提供的一个针对读写操作的锁,当对一个资源进行写操作的时候,那么所有线程无法对其进行读操作,当没有线程进行写操作的时候,资源的读操作不受限制。

可以看到,当使用读写锁的时候,只有在写完操作之后,读操作才开。

Lock和synchronized的区别:

1、Lock支持非阻塞的方式获取锁,并且能够中断等待锁的线程(lockInterruptibly 可以调用Thread.interrupt 进行中断)

2、Lock必须手动释放锁,所以应该在finally中编写释放锁的代码。synchronized可以自动释放锁。

3、Lock支持公平锁、非公平锁。synchronized只支持非公平锁。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值