java中的锁——列队同步器
队列同步器
队列同步器(AbstractQueuedSynchronizer)为实现依赖于先进先出 (FIFO) 等待队列的阻塞锁和相关同步器(信号量、事件,等等)提供一个框架。此类的设计目标是成为依靠单个原子 int 值来表示状态的大多数同步器的一个有用基础。子类必须定义更改此状态的受保护方法,并定义哪种状态对于此对象意味着被获取或被释放。假定这些条件之后,此类中的其他方法就可以实现所有排队和阻塞机制。子类可以维护其他状态字段,但只是为了获得同步而只追踪使用 getState()、setState(int) 和 compareAndSetState(int, int) 方法来操作以原子方式更新的 int 值。
队列同步器的使用
1: Protected 类别:
AbstractQueuedSynchornizer是抽象类,但是没有一个抽象方法。AbstractQueuedSynchornizer虽然没有抽象方法,但是提供了五个方法可以让我们在子类中重载,并且这五个方法都是空的实现且直接抛出异常,也就是说我们要使用这五个方法所提供的功能,必须在子类中自己实现,这也是模板方法模式的一种体现和使用。(为了将此类用作同步器的基础,需要适当地重新定义以下方法,这是通过使用 getState()、setState(int) 和/或 compareAndSetState(int, int) 方法来检查和/或修改同步状态来实现的:)
tryAcquire(int)//试图在独占模式下获取对象状态。tryRelease(int)//试图设置状态来反映独占模式下的一个释放。tryAcquireShared(int)//试图在共享模式下获取对象状态。tryReleaseShared(int)//试图设置状态来反映共享模式下的一个释放isHeldExclusively()//如果对于当前(正调用的)线程,同步是以独占方式进行的,则返回true。
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类别:
getState()//返回同步状态的当前值。setState(int)//设置同步状态的值。compareAndSetState(int, int)//如果当前状态值等于预期值,则以原子方式将同步状态设置为给定的更新值。
另外还有三个:hasWaiters、getWaitQueueLength、getWaitingThreads三个方法。
同步列队
队列同步器的实现依赖内部的同步队列来完成同步状态的管理。它是一个FIFO的双向队列,当线程获取同步状态失败时,同步器会将当前线程和等待状态等信息包装成一个节点并将其加入同步队列,同时会阻塞当前线程。当同步状态释放时,会把首节点中的线程唤醒,使其再次尝试获取同步状态。
节点是构成同步队列的基础,同步器拥有首节点和尾节点,没有成功获取同步状态的线程会成为节点加入该队列的尾部
......
java中的锁——列队同步器的更多相关文章
- 深入介绍Java中的锁[原理、锁优化、CAS、AQS]
1.为什么要用锁? 锁-是为了解决并发操作引起的脏读.数据不一致的问题. 2.锁实现的基本原理 2.1.volatile Java编程语言允许线程访问共享变量, 为了确保共享变量能被准确和一致地更新, ...
- 探究Java中的锁
一.锁的作用和比较 1.Lock接口及其类图 Lock接口:是Java提供的用来控制多个线程访问共享资源的方式. ReentrantLock:Lock的实现类,提供了可重入的加锁语义 ReadWrit ...
- Java中的锁[原理、锁优化、CAS、AQS]
1.为什么要用锁? 锁-是为了解决并发操作引起的脏读.数据不一致的问题. 2.锁实现的基本原理 2.1.volatile Java编程语言允许线程访问共享变量, 为了确保共享变量能被准确和一致地更新, ...
- Java中的锁原理、锁优化、CAS、AQS详解!
阅读本文大概需要 2.8 分钟. 来源:jianshu.com/p/e674ee68fd3f 一.为什么要用锁? 锁-是为了解决并发操作引起的脏读.数据不一致的问题. 二.锁实现的基本原理 2.1.v ...
- Java并发指南4:Java中的锁 Lock和synchronized
Java中的锁机制及Lock类 锁的释放-获取建立的happens before 关系 锁是java并发编程中最重要的同步机制.锁除了让临界区互斥执行外,还可以让释放锁的线程向获取同一个锁的线程发送消 ...
- Java 中的锁原理、锁优化、CAS、AQS 详解!(转)
1.为什么要用锁? 锁-是为了解决并发操作引起的脏读.数据不一致的问题. 2.锁实现的基本原理 2.1.volatile Java编程语言允许线程访问共享变量, 为了确保共享变量能被准确和一致地更新, ...
- java 中的锁 -- 偏向锁、轻量级锁、自旋锁、重量级锁(转载)
之前做过一个测试,详情见这篇文章<多线程 +1操作的几种实现方式,及效率对比>,当时对这个测试结果很疑惑,反复执行过多次,发现结果是一样的: 1. 单线程下synchronized效率最高 ...
- Java 中的锁
Java中的锁分类 在读很多并发文章中,会提及各种各样锁如公平锁,乐观锁等等,这篇文章介绍各种锁的分类.介绍的内容如下: 公平锁/非公平锁 可重入锁 独享锁/共享锁 互斥锁/读写锁 乐观锁/悲观锁 分 ...
- Java中的锁(转)
Java中的锁 锁像synchronized同步块一样,是一种线程同步机制,但比Java中的synchronized同步块更复杂.因为锁(以及其它更高级的线程同步机制)是由synchronized同步 ...
随机推荐
- ZooKeeper解决的问题
1.解决分布式单点问题 https://www.jianshu.com/p/08b76bd7a634 2.实现分布式环境数据的一致性.访问ZooKeeper树结构时,不同节点返回的数据是一致,不会引起 ...
- HDU-4460 Friend Chains(BFS&权为1所有最短路的最大值)
题目: For a group of people, there is an idea that everyone is equals to or less than 6 steps away fro ...
- 吴裕雄--天生自然ShellX学习笔记:Shell 函数
linux shell 可以用户定义函数,然后在shell脚本中可以随便调用. shell中函数的定义格式如下: [ function ] funname [()] { action; [return ...
- ccf201403-3 记录一个神tmwa了的代码 莫非我没看懂题。。。
#include <string.h> #include<cstdio> #include<stdio.h> #include <iostream> # ...
- [Python] 关于__init__.py
当目录结构为下面这样└── utils/│ ├── __init__.py│ └── config.py├── test.py 每个文件夹下都有__init__.py,一个目录如果包含了__init_ ...
- 用JS打开新窗口,防止被浏览器阻止的方法
相信做web前端或者使用JS的朋友都会遇到需要在新窗口打开页面的情况,现在浏览器大都具有弹出窗口拦截功能,所以传统的window.open()不再那么好用了.借鉴于网上查到的方法和我个人的实践,把弹出 ...
- docker安装(centos-7)
centos7安装docker:Docker 要求 CentOS 系统的内核版本高于 3.10 ,查看本页面的前提条件来验证你的CentOS 版本是否支持 Docker .通过 uname -r 命令 ...
- android studio 3.2 bundle.gradle 与2.2区别
参考:https://blog.csdn.net/MakerCloud/article/details/82898305
- [原]C++新标准之std::thread
原 总结 C++11 thread 概览 std::thread 类定义 各个成员函数的简单介绍 例子 更多 参考资料 概览 从C++11开始提供了线程的支持,终于可以方便的编写跨平台的线程代码了. ...
- Cell theory|Bulk RNA-seq|Cellar heterogeneity|Micromanipulation|Limiting dilution|LCM|FACS|MACS|Droplet|10X genomics|Human cell atlas|Spatially resolved transcriptomes|ST|Slide-seq|SeqFISH|MERFISH
生物信息学 Cell theory:7个要点 All known living things are made up of one or more cells. All living cells ar ...