Java AQS模型

Java 1.5之前,共享变量的互斥访问一般是通过synchronized代码块来实现,synchronizedJava早期只有重量级锁模式,在并发不是很高的环境下性能比较低,并且synchronized作为一个非公平锁,可能造成一些线程一直处于饥饿状态,也不支持主动的释放锁。因此从Java 1.5起引入了Java.util.concurrent并发包,在concurrent包中提供了一些实用的工具类来支持Java并发编程。

Semaphore:用于限制同时执行某个操作的线程数的同步辅助类。
CountDownLatch:用于等待其它线程完成操作的同步辅助类。
CyclicBarrier:一种同步辅助类,允许一组线程互相等待,直到所有线程都达到一个共同的屏障点。
ReentrantLock:可重入的互斥锁,用于控制多个线程对共享资源的访问。
ConcurrentHashMap:线程安全的哈希表,用于高并发环境下的 Map 操作。
CopyOnWriteArrayList:线程安全的列表,适合读多写少的场景。
BlockingQueue:阻塞队列,提供了线程安全的队列操作。

基本概念

在理解AQS之前,要先了解一下AQS框架中必要的技术概念:

  • 自旋锁

自旋是指当线程获取锁时,如果锁已经被独占,线程不会立即进入阻塞状态,而是会一直尝试去获取锁,直到获取锁成功或者超过尝试次数进入阻塞状态。
线程自旋获取锁成功的依据是通过CAS返回的值来判断,一般是返回true表示加锁成功。
自旋锁是一种轻量级锁,相比传统的synchronized锁,在并发竞争不激烈的情况下,可以避免线程频繁的阻塞和唤醒,减少系统的开销。但是在并发竞争激烈的情况下,自旋会导致线程一直尝试获取锁,浪费大量的CPU时间,性能可能不及重量级锁。

synchronized经过多个版本的优化,已经引入了轻量级锁(也是一种自旋锁),性能并不差。

  • 原子操作CAS
    CAS(compare and swap)是一种原子操作,它有三个参数: 内存位置(V)、预期原值(A)和新值(B),比较预期值与内存位置(V)的值,如果相等,则将该地址处的值设置为新值(V),否则不做任何操作。
    AQS中,无锁状态0,大于0就说明锁被已经被其他线程持有。当线程去加锁时可以拿着0去比较内存中的锁状态,如果想等,则将内存中的值加1,加锁成功;如果不相等,说明已经有其他的线程修改了锁状态值,表示加锁失败。CAS比较、赋值两个步骤是原子性的。
//自旋例子
for (;;) {
            Node t = tail;
            if (t == null) { // Must initialize
                if (compareAndSetHead(new Node()))
                    tail = head;
            } else {
                node.prev = t;
                //cas 操作
                if (compareAndSetTail(t, node)) {
                    t.next = node;
                    return t;
                }
            }
        }

AQS类结构

Java AQS (AbstractQueuedSynchronizer) Java 并发包中的一个抽象类,它使用一个volatile变量state来表示同步的状态(锁是否占用),每次只能一个线程占用这个状态资源进行操作,同时通过一个同步等待队列来管理没有获取到同步状态的线程。
在这里插入图片描述

AQS 获取锁流程

AQS定义了一套加锁、释放锁的流程,继承自AQS的工具类基本会遵守这套逻辑,如下是加锁逻辑:

// 1.尝试获取锁
if (!tryAcquire()){
 	for(;;){
        //2.将获取锁失败的线程添加到等待队列
        acquireQueued();
    }
 }
  1. 尝试获取锁:
    通过调用cas来设置state锁状态,如果设置成功则说明线程加锁成功。

  2. 加锁失败的线程添加到AQS等待队列:
    通过自旋cas将线程追加到等待队列的末尾,线程进入阻塞状态,并且等待它的前置节点唤醒它。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值