Java中的各种锁

1.公平锁和非公平锁
    公平锁:多个线程按照申请锁的顺序来获取锁;(类似排队打饭,先来后到)
非公平锁:多个线程并非按照申请锁的顺序,有可能后申请的线程先得到锁。(在高并发场景下,有可能会造成优先级反转或饥饿现象)
实现原理:多线程场景下,如果去检查锁维护的等待队列,如果队列为空或当前线程是队列中的队首元素则获取锁,否则就会加入等待队列,按照FIFO的规则等到排队到自己再获取锁。非公平锁上来就尝试去抢占锁,没有成功再排队。
ReentrantLock 默认是非公平锁,比公平锁性能好,吞吐量更大。
Synchronized 也是非公平锁.

2.可重入锁和递归锁
可重入锁就是递归锁,就相当于一个别名.
可重入锁:同一线程外层方法获取锁后,内层递归调用的方法仍自动获取这把锁。
即,线程可以进入任何一个它已经拥有的锁所同步着的代码块
ReentrantLock/Synchronized 就是一个经典的可重入锁
作用:防止死锁

锁的基本原理是,基于将多线程并行任务通过某一种机制实现线程的串行执行,从而达到线程安全性的目的。

3.自旋锁
尝试获取锁的线程不会阻塞,而是采用死循环的方式去获取锁
这样做的好处是减少了线程上下文切换的消耗,缺点是死循环很耗CPU。
下面这段是 CAS 自旋锁的源码

public final int getAndAddInt(Object var1, long var2, int var4) {
    int var5;
    do {
        var5 = this.getIntVolatile(var1, var2);
    } while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));

    return var5;
}

生活中自旋的例子:一个人饿了到食堂等着开饭;求人办事在别人办公室一直等着别人有空;

4.读写锁/互斥锁
共享锁:即读锁;指该锁可以同时被多个线程持有。
独占锁:即写锁;一次只能被一个线程所持有。ReentrantLock/Synchronized就是独占锁。
互斥锁:
读 - 读 能共存;
读 - 写 不能共存;
写 - 写 不能共存;

读写锁维护了一对锁,一个读锁、一个写锁; 一般情况下,读写锁的性能都会比排它锁好,因为大多数场景读是多于写的。
在读多于写的情况下,读写锁能够提供比排它锁更好的并发性和吞吐量.

5.分段锁

6.乐观锁/悲观锁
基于乐观锁以及自旋锁来优化了 synchronized 的加锁开销;
同时在重量级锁阶段,通过线程的阻塞以及唤醒来达到线程竞争和同步的目的。

7.偏向锁/轻量级锁/重量级锁

8.独享锁/共享锁

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值