队列同步器

队列同步器(AbstractQueuedSynchronizer)为实现依赖于先进先出 (FIFO) 等待队列的阻塞锁和相关同步器(信号量、事件,等等)提供一个框架。此类的设计目标是成为依靠单个原子 int 值来表示状态的大多数同步器的一个有用基础。子类必须定义更改此状态的受保护方法,并定义哪种状态对于此对象意味着被获取或被释放。假定这些条件之后,此类中的其他方法就可以实现所有排队和阻塞机制。子类可以维护其他状态字段,但只是为了获得同步而只追踪使用 getState()setState(int)compareAndSetState(int, int) 方法来操作以原子方式更新的 int 值。

队列同步器的使用

1: Protected 类别:

AbstractQueuedSynchornizer是抽象类,但是没有一个抽象方法。AbstractQueuedSynchornizer虽然没有抽象方法,但是提供了五个方法可以让我们在子类中重载,并且这五个方法都是空的实现且直接抛出异常,也就是说我们要使用这五个方法所提供的功能,必须在子类中自己实现,这也是模板方法模式的一种体现和使用。(为了将此类用作同步器的基础,需要适当地重新定义以下方法,这是通过使用 getState()setState(int) 和/或 compareAndSetState(int, int) 方法来检查和/或修改同步状态来实现的:)

2:public final类别

除了上述protected的方法之外,还有一个关键的类别就是public final,这是我们可以直接使用的方法,称之为模板方法,当我们实现自定义的同步组件的时候,我们可以调用这些模板方法获取我们需要的东西。

(1) Void acquire(int arg)   //独占式获取同步状态,如果当前线程获取同步状态成功,则由该方法返回,否则,将进入同步队列等待,该方法将会调用重写的tryAcquire(int arg) 方法

(2) Void acquireInterruptibly(int arg)   //与acquire相同,但是该方法会响应中断,当前线程未获取到同步状态而进入同步队列中,如果当前线程被中断,则该方法会抛出InteruptedException并返回

(3) Boolean tryAcquireNanos(int arg,long nanos)   //在acquireInterruptibly(int arg )的基础上增加了超时限制 如果当前线程在超时时间内没有获取到同步状态,那么将会返回false,如果获取到了返回为true

(4) Void acquireShared(int arg)   //共享式的获取同步状态,如果当前线程为获取到同步状态,将会进入同步队列等待,与独占式获取的主要区别是在同一时刻可以有多个线程获取到同步状态。

(5) Void acquireSharedInterruptibly(int args)   //与acquireShared(int arg)相同,该方法响应中断

(6)boolean tryAcquireSharedNanos(int arg,long nanos)   //在acquireShared(int arg) 基础上增加了超时限制

(7)  boolean  release(int arg)   //独占式的释放同步状态,该方法会在释放同步状态之后,将同步队列

(8)  boolean releaseShared(int arg)  // 共享式的释放同步状态

(9) Collection<Thread> getQueuedThreads()   //获取等待在同步队列上的线程集合。

3: Protected fianl类别:

另外还有三个:hasWaiters、getWaitQueueLength、getWaitingThreads三个方法。

同步列队

队列同步器的实现依赖内部的同步队列来完成同步状态的管理。它是一个FIFO的双向队列,当线程获取同步状态失败时,同步器会将当前线程和等待状态等信息包装成一个节点并将其加入同步队列,同时会阻塞当前线程。当同步状态释放时,会把首节点中的线程唤醒,使其再次尝试获取同步状态。

节点是构成同步队列的基础,同步器拥有首节点和尾节点,没有成功获取同步状态的线程会成为节点加入该队列的尾部

同步器包含了两个节点类型的引用,一个指向头节点,而另一个指向尾节点。
如果一个线程没有获得同步队列,那么包装它的节点将被加入到队尾,显然这个过程应该是线程安全的。因此同步器提供了一个基于CAS的设置尾节点的方法:compareAndSetTail(Node expect,Node update),它需要传递一个它认为的尾节点和当前节点,只有设置成功,当前节点才被加入队尾
 
同步队列遵循FIFO(先进先出),首节点是获取同步状态成功的节点,首节点线程在释放同步状态时,将会唤醒后继节点,而后继节点将会在获取同步状态成功时将自己设置为首节点

......

java中的锁——列队同步器的更多相关文章

  1. 深入介绍Java中的锁[原理、锁优化、CAS、AQS]

    1.为什么要用锁? 锁-是为了解决并发操作引起的脏读.数据不一致的问题. 2.锁实现的基本原理 2.1.volatile Java编程语言允许线程访问共享变量, 为了确保共享变量能被准确和一致地更新, ...

  2. 探究Java中的锁

    一.锁的作用和比较 1.Lock接口及其类图 Lock接口:是Java提供的用来控制多个线程访问共享资源的方式. ReentrantLock:Lock的实现类,提供了可重入的加锁语义 ReadWrit ...

  3. Java中的锁[原理、锁优化、CAS、AQS]

    1.为什么要用锁? 锁-是为了解决并发操作引起的脏读.数据不一致的问题. 2.锁实现的基本原理 2.1.volatile Java编程语言允许线程访问共享变量, 为了确保共享变量能被准确和一致地更新, ...

  4. Java中的锁原理、锁优化、CAS、AQS详解!

    阅读本文大概需要 2.8 分钟. 来源:jianshu.com/p/e674ee68fd3f 一.为什么要用锁? 锁-是为了解决并发操作引起的脏读.数据不一致的问题. 二.锁实现的基本原理 2.1.v ...

  5. Java并发指南4:Java中的锁 Lock和synchronized

    Java中的锁机制及Lock类 锁的释放-获取建立的happens before 关系 锁是java并发编程中最重要的同步机制.锁除了让临界区互斥执行外,还可以让释放锁的线程向获取同一个锁的线程发送消 ...

  6. Java 中的锁原理、锁优化、CAS、AQS 详解!(转)

    1.为什么要用锁? 锁-是为了解决并发操作引起的脏读.数据不一致的问题. 2.锁实现的基本原理 2.1.volatile Java编程语言允许线程访问共享变量, 为了确保共享变量能被准确和一致地更新, ...

  7. java 中的锁 -- 偏向锁、轻量级锁、自旋锁、重量级锁(转载)

    之前做过一个测试,详情见这篇文章<多线程 +1操作的几种实现方式,及效率对比>,当时对这个测试结果很疑惑,反复执行过多次,发现结果是一样的: 1. 单线程下synchronized效率最高 ...

  8. Java 中的锁

    Java中的锁分类 在读很多并发文章中,会提及各种各样锁如公平锁,乐观锁等等,这篇文章介绍各种锁的分类.介绍的内容如下: 公平锁/非公平锁 可重入锁 独享锁/共享锁 互斥锁/读写锁 乐观锁/悲观锁 分 ...

  9. Java中的锁(转)

    Java中的锁 锁像synchronized同步块一样,是一种线程同步机制,但比Java中的synchronized同步块更复杂.因为锁(以及其它更高级的线程同步机制)是由synchronized同步 ...

随机推荐

  1. Eclipse打开,出现Initializing Java Tooling “has encountered a problem错误,而且鼠标悬停在没有导包的类上面不会出现import信息。

    问题1:打开eclipse,出现了Initializing Java Tooling “has encountered a problem,点开详细信息,报的是空指针异常. 问题2:鼠标悬停在没有导包 ...

  2. 18 11 13 装了ssd 继续 网络通信 tcp 客户端的创建

    import socket def main(): # 1. 买个手机(创建套接字 socket) 联通公司建立了一个信号塔 tcp_server_socket = socket.socket(soc ...

  3. 84.常用的返回QuerySet对象的方法使用详解:select_related, prefetch_related

    1.select_related: 只能用在一对多或者是一对一的关联模型之间,不能用在多对多或者是多对一的关联模型间,比如可以提前获取文章的作者,但是不能通过作者获取作者的文章,或者是通过某篇文章获取 ...

  4. mysql安装完之后,登陆后发现只有两个数据库

    mysql安装完之后,登陆后发现只有两个数据库:mysql> show databases;+--------------------+| Database           |+------ ...

  5. PAT Advanced 1041 Be Unique (20) [Hash散列]

    题目 Being unique is so important to people on Mars that even their lottery is designed in a unique wa ...

  6. day59-mysql-存储过程、函数、事务、锁、备份

    存储过程.函数不是重要的内容. 三. 存储过程:类似于函数(方法),简单的说存储过程是为了完成某个数据库中的特定功能而编写的语句集合, 该语句集包括SQL语句(对数据的增删改查).条件语句和循环语句等 ...

  7. Maven--设置Http代理

    <settings> ... <proxies> <proxy> <id>my-proxy</id> <active>true& ...

  8. Linux进程的诞生和消亡

    1.进程的诞生 (1).进程0和进程1 (内核里边的固有的) (2).fork函数和vfork函数用于新进程的产生 2.进程的消亡 (1).正常终止和异常终止 (2).进程在运行时需要消耗系统资源(内 ...

  9. Openstack 使用Centos官方镜像创建实例记录

    Openstack 使用Centos官方镜像创建实例记录 准备centos镜像 官方地址:http://cloud.centos.org/centos/7/images 可以看到有各种版本的镜像,我在 ...

  10. 了解SSL证书从HTTPS开始 开发者绕不开的“劫”

    微信小程序上线已经有很长一段时间了,而开发者在接入小程序的过程中,会遇到一些问题,例如小程序要求必须通过HTTPS完成服务端通信,开发者需搭建HTTPS服务,进行 SSL 证书申请.部署,完成HTTP ...