【多线程进阶】——同步器AQS详解

前言

学习多线程,一定会接触过线程安全的问题,线程安全我理解的意思就是单线程执行和多线程执行保证结果都是一致的,使用多线程只是为了达到快的目的,而不会产生不一样的结果,那问题就来了,如何保证线程安全呢,肯定的答案是锁,那么用哪一种锁,如何使用,我们必须锁的内部机制做一下了解!

内容

在学习AQS之前我们需要解决几个问题:

1.为什么线程没有按照我们开启的顺序执行?
因为JMM(java内存模型)不保证未同步的程序的执行结果与该程序在顺序一致性模型中的执行结果一致,因为不同的机器上都会存在编译器排序和处理器重排序,重排序会改变程序执行的结果。

2.如何保证线程安全?
加入指令可以保证编译器不能再重新排序操作,比如voliate和锁,在编译器生成字节码的时候,会在指令序列中插入内存屏障禁止特定类型的处理器重排序。
3.都有哪几种锁,内部机制是什么?

synchronized和ReentranLock,synchronized在jdk1.6之前都是重量级锁,而jdk1.6之后和ReentranLock锁的级别就差不多,只不多ReentranLock特性要比synchronized多一些。synchronized是对象级别锁,主要存在于java对象头中。而ReentranLock内部实现就是我们今天要讲解的重点AQS同步器。
4.AQS原理

  1. 声明了共享变量volatile
  2. 使用CAS原子条件更新实现线程同步

5.AQS详解

AQS定义两种资源共享方式:Exclusive(独占,只有一个线程能执行,如ReentrantLock)和Share(共享,多个线程可同时执行,如Semaphore/CountDownLatch)。

不同的自定义同步器争用共享资源的方式也不同。自定义同步器在实现时只需要实现共享资源state的获取与释放方式即可,至于具体线程等待队列的维护(如获取资源失败入队/唤醒出队等),AQS已经在顶层实现好了。

自定义同步器实现时主要实现以下几种方法:

  • isHeldExclusively():该线程是否正在独占资源。只有用到condition才需要去实现它。
  • tryAcquire(int):独占方式。尝试获取资源,成功则返回true,失败则返回false。
  • tryRelease(int):独占方式。尝试释放资源,成功则返回true,失败则返回false。
  • tryAcquireShared(int):共享方式。尝试获取资源。负数表示失败;0表示成功,但没有剩余可用资源;正数表示成功,且有剩余资源。
  • tryReleaseShared(int):共享方式。尝试释放资源,成功则返回true,失败则返回false。

AQS是(AbstractQueuedSynchronized)和ReentranLock锁,以及一些同步框架Semphore,Countdownlatch都是实现了AQS的某一些方法,直接使用了AQS,所以在这里采用的模板设计模型。

    private Node addWaiter(Node mode) {
        Node node = new Node(Thread.currentThread(), mode);
        // Try the fast path of enq; backup to full enq on failure
        Node pred = tail;
        if (pred != null) {
            node.prev = pred;
            if (compareAndSetTail(pred, node)) {
                pred.next = node;
                return node;
            }
        }
        enq(node);
        return node;
    }

总结

当这道这层理论之后分析同步锁代码就会非常简单,因为主要分析他们获取锁和释放锁之间的不同即可,模板设计模式为我们做到了这一点,你有没有get到?

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值