【Java多线程】Java中都有哪些锁


一、乐观锁 & 悲观锁

  
  乐观锁:指的是在操作数据的时候非常乐观,认为别人不会同时修改数据,因此乐观锁默认是不会上锁的,只有在执行更新的时候才会去判断在此期间别人是否修改了数据,如果别人修改了数据则放弃操作,否则执行操作。

  悲观锁:指的是在操作数据的时候比较悲观,认为别人一定会同时修改数据,因此悲观锁在操作数据时是直接把数据上锁,直到操作完成之后才会释放锁,在上锁期间其他人不能操作数据。

  乐观锁和悲观锁各有优劣,在读操作多的场景适用乐观锁,因为数据不会被其他线程频繁修改,少了加锁和释放锁的开销性能更好;而在写操作多的场景下乐观锁就不适用了,数据会被其他线程修改就导致频繁更新失败。在 Java 中,CAS 机制属于乐观锁,synchronized 关键字的实现属于悲观锁。

二、独占锁 & 共享锁

  
  共享锁:也叫读锁,可以查看数据,但是不能修改和删除的一种数据锁,加锁后其他的用户可以并发读取,但不能修改、增加、删除数据,该锁可被多个线程持有,用于资源数据共享。

  独占锁:也叫写锁、排它锁,该锁每一次只能被一个线程所持有,加锁后任何线程试图再次加锁都会被阻塞,直到当前线程解锁。

三、公平锁 & 非公平锁

  
  公平锁:有多个线程按照申请锁的顺序来获取锁,就是说在一个线程组里面,能够保证每个线程都能拿到锁。

  非公平锁:获取锁的方式是随机的,保证不了每个线程都能拿到锁,会存在有的线程饿死,一直拿不到锁。

  非公平锁性能高于公平锁,因为非公平锁的竞争更消耗 CPU 资源。在 Java 中,synchronized 关键字是非公平锁,ReentrantLock 通过参数控制,可以是公平锁也可以是非公平锁,默认使用非公平锁。

四、可重入锁 & 不可重入锁

  
  可重入锁:可以重复使用的锁,当一个线程获取锁之后,这个线程可以再次获取本对象实例上的锁,而其他的线程是不可以的。

  不可重入锁:不可以重复使用的锁。

  举个例子:假设有个类的A、B连个方法都加了锁,可重入锁在获取了A方法的锁之后可以直接访问B方法,而不可重入锁获取了A方法的锁之后访问B方法,需要等A方法的锁释放之后再次获取锁才能访问。Java 中的 synchronized 和 ReentrantLock 都是可重入锁。

五、互斥锁 & 自旋锁

  
  互斥锁:锁只能被一个线程持有,当一个线程获取锁之后另外一个线程加锁就会失败,而加锁失败的线程会释放掉 CPU 资源。

  自旋锁:和互斥锁有点类似,区别在于加锁失败后不会释放 CPU 资源,而是通过循环的方式尝试去获取锁。

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

  
  偏向锁:它会偏向于第一个访问锁的线程,如果在运行过程中,锁只有一个线程访问,不存在多线程争用的情况,则线程是不需要触发同步的,这种情况下,就会给线程加一个偏向锁。

  轻量级锁:如果在运行过程中,遇到了其他线程抢占锁,则持有偏向锁的线程会被挂起,JVM 会消除它身上的偏向锁,将锁恢复到标准的轻量级锁。

  重量级锁:如果在尝试加轻量级锁的过程中,CAS 操作无法成功,这是有一种情况就是其它线程已经为这个对象加上了轻量级锁,这是就要进行锁膨胀,将轻量级锁变成重量级锁。

七、分段锁

  
  分段锁其实就是对锁的粒度的一种细化,以此来提高性能和灵活度。比如 Java7 中的 ConcurrentHashMap 就是采用的分段锁。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

砍光二叉树

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值