Java 锁

本篇计划总结一下,Java中最基本的锁,以及springboot分布式锁的redis实现

1 锁 一般是抽象的概念,Java中有具体的对象和关键字,来实现这些锁,下面介绍这些锁

      synchronized  ,这是一个关键字,用来做线程锁,也是悲观锁 同步锁,当一个线程执行了被synchronized修饰的方法或代码块时,其他线程,将无法访问这个锁内的代码块,但是可以访问持有这个锁的线程的其他代码块。

       非公平性:多个线程竞争一个synchronized 锁时,是随机分配给某个线程的,所以,synchronized 也是非公平锁。

        可重入性:同一个线程,这个线程可以反复进入自己持有锁的代码块,这样做,每次进入后,持有的锁会+1,会记录持有锁的线程id。

        static synchronized:锁住一个class类(普通synchronized锁住当前对象,即this)

        偏向锁,轻量级锁,重量级锁:synchronized锁住一个代码块后,其他线程无法访问,这会导致性能低下,因此有了这三种锁来优化synchronized。

         偏向锁:一个锁,一直被同一个线程访问,当这个线程已经获取过这个锁,再次想要获取这个锁时,不需要加锁就能访问锁内的代码块。

          轻量级锁:出现一个新的线程,对偏向锁中的线程进行竞争一个锁,此时,新的线程会进入自旋,即持续等待,此时,就是轻量级锁。

          重量级锁:轻量级锁的自旋一直存在,自旋一定次数后,升级为重量级锁,重量级锁就是最早的synchronized,会拒绝其他线程访问被锁住的代码块,这些线程将被挂起,进入阻塞。

2 CAS

这是一种乐观锁的实现:先查询需要修改的值,然后要进行修改时再次查询,如果两次结果一致,可以进行后面的修改这个值的操作,否则不断重复这个流程,进入自旋,直到可以修改,或者放弃修改。

 具体实现类:AtomicInteger  AtomicBoolean 等

3 ReenTrantLock

sync类重入获取资源:一种对同一个线程可重入锁,每次同一个线程重入,则state记录次数并+1,如果之前没有线程持有锁,则cas操作,将这个次数变为1。使用CAS来修改state的值,获取锁的sync类继承了AQS。

释放锁:对于同一个线程,每次将它的state -1,当state变成0的时候,将持有这个锁的线程清空,具体方法:setExclusiveOwnerThread(null)

非公平获取锁和资源:直接cas设置state,成功获取锁,失败进入队列等待。(非公平体现在等待队列之外的线程也会用同样的方式获取锁)

公平地获取锁和资源:state为0,要去cas给这个线程获取锁前,先判断这个线程是否在等待队列中。

4 ReentrantReadWriteLock 

读写锁,分为读锁和写锁,读锁持有的时候不能再获取该资源的写锁,其他线程都能读,写锁持有的时候,其他线程不能读。

   写锁获取锁:先查看资源是否被其他线程持有锁,再查看写锁的数量,可以则重入,state+1

                具体情况:如果写锁数量不为0,查询持有锁线程是否为当前线程,是则重入,不是则                                      拒绝,可以重入还有判断是否超过写锁数量上限。

   写锁释放:直接getstate-1,直到清除完,然后将持有资源的线程id置为null。                              

   获取读锁:有写锁无法获取,只有读锁时,判断持有锁数量,不超过上限,state+1

   读锁释放:使用CAS修改state 这个锁的数量。

5 AQS

一个抽象类,类中一些关键对象:

         1 Node, 关键变量都用volatile修饰,事实上是一个双向链表,记录了上一个节点和下一个节             点的信息。exclusiveOwnerThread 记录当前持有锁的线程id,

   

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值