zoukankan      html  css  js  c++  java
  • java并发编程之美——高级篇(三)

    一、抽象同步队列AQS概述

    1.什么是AQS?

    AbstractQueuedSynchronizier抽象同步队列。它是实现同步器的基本组件。并发包中锁的底层就是使用AQS实现的。首先,AbstractQueuedSynchronizier类继承AbstractOwnableSynchronizer类。包含Node类型和ConditionObject类型的成员变量。AQS是一个FIFO的双向队列,内部通过节点head和tail记录队首和队尾的元素,队列元素类型为Node。

    AQS的类图结构:AQS实现AbastractOwnableSynchronizer,包含内部类Node和ConditionObject

    Node中的thread用来存放进入AQS里面的线程,Node节点内部的SHARED用来标记该线程是获取共享资源时被阻塞挂起后放入AQS队列的线程,EXCLUSIVE用来标记获取独占资源时被挂起后放入AQS队列的,waitStatus记录当前线程的等待状态,可以为CANCELLED(线程被取消了)、SIGNAL(线程需要被唤醒)、CONDITION(线程在条件队列里面等待)、PROPAGATE(释放共享资源时需要通知其他节点);prev记录当前节点的前驱节点,next记录当前节点的后继节点。

    AQS中的变量state。、

    AQS中的内部类ConditionObject。用来结合锁实现线程同步。ConditionObject可以访问AQS对象内部的变量,比如state和AQS队列。ConditionObject是条件变量,每个条件变量对应一个条件队列,用来存放调用条件变量的await方法后被阻塞的线程。

    对于AQS来说,线程同步的关键在于对state的修改,根据state是否属于一个线程,操作state的方式分为独占方式和共享方式。

    获取与释放锁资源需要实现类重写获取与释放的方法,根据不同的实现也就产生了独占锁和共享锁。重写isHeldExclusively方法,判断是独占锁还是共享锁。

    2.AQS条件变量 ConditionObject

    条件变量的await,notify用来配合锁实现线程同步。

    二、独占锁ReentrantLock的原理

    ReentrantLock是可重入的独占锁。也是通过AQS实现。

    主要方法:

    (1)void lock()

    获取锁,根据ReentrantLock的构造参数来获取一个公平锁或非公平锁。

    (2)void lockInteruptibly

    获取锁,不同在于,该方法会对中断进行相应,当前线程在调用该方法是,如果其他线程调用了当前线程的interrupt()方法,该方法会抛出InterruptedException异常。

    (3)boolean tryLock()

    尝试获取锁,如果当前锁没有被其他线程占用,则当前线程获取该锁并返回true,否则返回false。该方法不会引起当前线程阻塞。

    (4)boolean tryLock(long timeout,TimeUnit unit)

    超时未获取到锁返回false

    (5)void unlock()

    state减1,更新可重入次数。如果为0则释放锁。

    三、ReentranReadWriteLock的原理

    ReentranReadWriteLock采用读写分离的策略,允许多个线程同时获取读锁。

    类图结构:

     实现了ReadWriteLock接口。内部维护一个ReadLock和一个WriteLock。它们依赖Sync实现具体功能。而Sync继承了AQS,并且也提供了公平锁和非公平锁的实现。AQS中维护一个state状态,而ReentranReadWriteLock用state的高16位表示读状态,也就是读锁的次数,低16位表示写锁的线程的可重入次数。

    四、JDK新增的StampLock

    JDK8新增的一个锁,提供了三种模式的读写控制。获取锁时会返回一个long类型的stamp,失败会返回0。当调用释放锁和转换锁的方法时,需要传入该参数。

    ------------------------------------------------未完待续-------------------------------------------------

  • 相关阅读:
    mysql怎么导入大文件的sql文件
    php函数研究
    php实现实现代码多主从,切换,轮询,健康检查
    php实现单个用户禁止重复登录,防止同一用户同时登陆
    php使用p3p实现cookies跨域设置 实现单点登录,全站登录
    实现页面浏览统计
    遍历目录删除指定MD5值的文件
    boot.img的修改
    “逃离大厦”游戏的破解
    Android漏洞——将Android恶意代码隐藏在图片中
  • 原文地址:https://www.cnblogs.com/feifei123/p/12682586.html
Copyright © 2011-2022 走看看