并发下的锁

在真实场景中锁,锁并没有那么多,很多锁只是从不同功能特性,设计,以及锁的状态这些不同的侧重点来说明的,因此我们根据不同的分类来理解。
在这里插入图片描述

1.公平锁和非公平锁

公平锁

指线程在等待获取同一个锁的时候,是严格按照申请锁的时间顺序来进行的,这就意味着在程序运作的时候,不会有线程执行不到的情况,但需要额外的资源维护这种顺序所以效率相对于非公平锁会差点。

非公平锁

随机线程获取锁,效率比公平锁相对高些。

2.重入锁(递归锁)与不可重入锁(自旋锁)

重入和递归,不可重入和自旋虽然名字不同,但是确实是同一种锁,只是从锁的表现跟实现方式的角度来命名而。

重入锁(递归锁)

当一个线程获取A锁以后,若后续方法运行被A锁锁住的话,当前线程也是可以直接进入的。

 public  class Demo {
        public Lock lockA;

        public Demo(Lock lock) {
            lockA = lock;
        }

        public void methodA() {
            lockA.lock();
            methodB();
            System.out.println("methodA");
            lockA.unlock();
        }

        public void methodB() {
            lockA.lock();
            System.out.println("methodB");
            //dosm
            lockA.unlock();
        }
    }

当我们运行methodA()的时候,线程获取了lockA,然后调用methodB()的时候发现也需要lockA,由于这是一个可重入锁,所以当前线程也是可以直接进入的。在java中,synchronized跟ReetrantLock都是可重入锁。

不可重入锁(自旋锁)

是指当一个线程在获取锁的时候,如果锁已经被其它线程获取,那么该线程将循环等待,然后不断的判断锁是否能够被成功获取,直到获取到锁才会退出循环。在Java中,那就是CAS。

CAS机制中使用了三个基本操作数,内存地址V,旧的预期值A,要修改的新值B。更新共享变量的时候,只有当变量的预期值A和内存地址V当中的实际值是相同的,才会将内存地址V对应的值修改为B。

3.悲观锁与乐观锁

这两种锁呢,不是一种具体的锁,而是泛指看待并发的程度。

悲观锁

有一个悲观的心态,即每次取数据的时候,都会认为该数据会被修改,所以必须加一把锁才安心。
有:ReentrantLack ,synchronized

乐观锁

乐观锁认为同一个数据不会发生并发操作的行为,所以取的时候不会加锁,只有在更新的时候,会通过例如版本号之类来判断数据是否被修改。
CAS,AtomicInteger

4.共享锁与拍他锁

这两种锁的概念比较多的出现在数据库的事物中。

共享锁

也称为读锁或者S锁,如果事物对数据A加上共享锁后,其他事物只能对A再加共享锁,不能加排他锁。获准共享锁的事务只能读数据,不能修改数据。在Java中的ReetrantReaderWriteLock()也是如此。

排他锁

也称独占锁、写锁或X锁。如果事务对数据A加上排他锁后,则其他事务不能再对A加任何类型的锁。获得排他锁的事物既能读数据又能修改数据。

5.分布式锁

我们上面聊的这些锁,都是在单个程序上面不同线程之间来实现的,那么我们不同程序需要去竞争同一块资源的时候,就需要分布式锁了。我们可以通过redis、zookeeper等中间件来实现分布式锁。

参考

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值