线程安全-4 AQS&Lock&ReentrantLock

一.什么是AQS?

1.AQS,AbstractQueuedSynchronizer,抽象队列同步器,是一个用于构建锁和同步器的框架。

2.基于AQS实现的锁或同步器有:可重入锁ReentrantLock、计时锁CountDownLatch、信号量Semaphore等

3.AQS三大核心

(1)state:用整型变量state来标记共享变量的状态,多线程通过操作state来实现锁或同步器机制,state需要用volatile修饰。

(2)queue:AQS内部维护一个基于FIFO算法和双向链表实现的队列。若线程请求共享变量失败,则会被包装成一个Node节点,存到队列尾部。当共享变量空闲,则会唤醒队列的第一个线程去操作变量。

(3)CAS:多线程操作state是通过CAS操作完成的。

4.AQS的两种模式:独占锁和共享锁

(1)独占锁:共享变量只能被一个线程获取到。state初值为0,表示无锁状态,线程可以使用;当线程获取到锁,则通过CAS操作对state加1,表示变量被上锁,其他线程不能使用;当state为0时会唤醒队列中的第一个线程。

(2)共享锁:共享变量可以被多个线程获取到。state初值为N,表示可以被N个线程使用;当线程获取到锁,则通过CAS操作对state减1;当state为0时,其他线程陷入阻塞;当有一个线程释放锁,就会唤醒队列中的第一个线程。

二.synchronized和Lock的区别

1.语法层面

(1)synchronized是关键字,源码在jvm中,由c++实现

(2)Lock是jdk提供的一个接口,由java实现

2.释放锁的方式

(1)synchronized在执行完代码块或者执行发生异常时,会自动释放锁

(2)Lock在执行完代码或者执行发生异常时,都不会主动释放锁,必须调用unlock()手动释放锁

3.功能层面

synchronized和Lock都属于悲观锁,实现了锁机制基本的互斥、同步、锁重入功能;但Lock锁又具有额外的功能

(1)公平锁:可以选择将锁设置为公平锁,即线程按照等待顺序依次获取锁。而synchronized是所有线程一同争抢锁。

(2)可打断:如果线程尝试用lockInterruptibly()获取锁,则线程在等待锁的过程中可以调用interrupt()打断。而synchronized如果在线程等待锁的过程中调用interrupt()打断,会抛出异常。

(3)计时等待:线程使用tryLock()方法获取锁

        a.tryLock()是一个非阻塞方法,如果线程获取到锁,则返回true;如果线程获取不到锁,则直接返回false,不会阻塞等待。

        b.tryLock(long time,TimeUnit unit)用于计时等待,如果线程获取到锁,则返回true;如果线程获取不到锁,会进入计时等待;若在等待时间内获取到锁,则返回true;若超时仍获取不到锁,则返回false。

        c.通过tryLock()方式获取锁,既能知道线程是否获取到锁,还能避免线程陷入长时间阻塞。而synchronized会永久阻塞获取不到锁的线程,且无法知道当前线程是否获取到锁。

(4)多条件等待:可以通过Lock提供的newCondition()方法创建多个条件;线程在获取到锁后,可以通过调用Condition()的await()方法进入等待状态,此时会释放锁;其他线程在获取到锁后,可以通过调用Condition()的signal()方法唤醒因当前条件而进入等待的线程。Lock可以创建多个Condition,对不同线程进行灵活地等待与唤醒。而synchronized只能通过唯一的锁对象来关联等待与唤醒线程。

三.ReentrantLock的实现原理

1.ReentrantLock是支持重入的独占锁,基于AQS框架和Lock接口实现。

2.ReentrantLock提供了公平锁和非公平锁两种模式:公平锁模式下,所有线程会按照等待的先后顺序依次获取锁;非公平锁模式下,对于新进入的线程,会直接通过CAS操作尝试获取锁,CAS操作失败才进入队尾排队。

3.当一个线程想要获取锁:

(1)通过CAS操作修改锁的状态值state,如果操作成功则获取锁

(2)如果CAS操作失败,说明锁被其他线程持有,当前线程进入等待

4.当一个线程想要释放锁:

(1)通过CAS操作修改锁的状态值state

(2)唤醒队列的第一个线程

(3)将该线程从队列移除

5.ReentrantLock支持可重入的特性,即同一线程可以多次获取锁而不陷入阻塞。线程每重入一次锁,就通过CAS对state加1;每释放一次锁就通过CAS对state减1。只有当state为0时才唤醒下一个线程。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值