队列同步器AbstractQueuedSynchronizer
|
方法名称
|
描述
|
|
boolean tryAcquire(int arg)
|
独占式获取同步状态。实现该方法需要查询当前状态并判断同步状态是否符合预期,然后再进行cas设置同步状态。(因为可能多个线程都在获取)
|
|
boolean tryRelease(int arg)
|
独占式释放同步状态,成功返回true,失败返回false。
|
|
int tryAcquireShared(int arg)
|
共享式获取同步状态,获取成功则返回值>=0
|
|
boolean tryReleaseShared(int arg)
|
共享式释放同步状态,成功返回true,失败返回false。
|
|
boolean isHeldExclusively()
|
判断同步器是否在独占模式下被占用,一般用来表示同步器是否被当前线程占用
|
|
方法
|
描述
|
|
int getState()
|
获取当前同步状态
|
|
void setState(int newState)
|
设置当前同步状态
|
|
boolean compareAndSetState(int expect, int update)
|
使用CAS设置当前状态,保证状态更新的原子性。只有当state为expect时,才能设置成功。expect相当于乐观锁的version
|
|
方法
|
描述
|
|
void acquire(int arg)
|
独占式获取同步状态,该方法会调用子类重写的tryAcquire(int arg),如果tryAcquire返回true则该方法直接返回,否则先将当前线程加入同步队列的尾部,然后阻塞当前线程
|
|
void acquireInterruptibly(int arg)
|
和acquire类似,只是当线程获取同步状态失败被阻塞后,可以响应中断,收到中断后将会取消获取同步状态
|
|
boolean tryAcquireNanos(int arg, long nanosTimeout)
|
在acquireInterruptibly的基础上加了超时限制,如果在超时时间内获取到同步状态返回true,否则返回false
|
|
boolean release(int arg)
|
独占式释放同步状态,该方法会在释放同步状态后将第一个节点(对应刚刚释放同步状态的线程)的后继节点对应的线程唤醒。
|
|
void acquireShared(int arg)
|
共享式获取同步状态,该方法会调用子类重写的tryAcquireShared(int arg),如果tryAcquireShared返回true则该方法直接返回,否则先将当前线程加入同步队列的尾部,然后阻塞当前线程
|
|
void acquireSharedInterruptibly(int arg)
|
和acquireShared类似,只是当线程获取同步状态失败被阻塞后,可以响应中断,收到中断后将会取消获取同步状态
|
|
boolean tryAcquireSharedNanos(int arg, long nanosTimeout)
|
在acquireSharedInterruptibly的基础上加了超时限制,如果在超时时间内获取到同步状态返回true,否则返回false
|
|
boolean releaseShared(int arg)
|
共享式的释放同步状态
|
|
Collection<Thread> getQueuedThreads()
|
获取等待在同步队列上的线程集合
|
public class Mutex implements Lock {
private final Sync sync = new Sync();
//静态内部类,自定义同步器,锁的功能通过它来实现
private static class Sync extends AbstractQueuedSynchronizer{
//是否处于占用状态
protected boolean isHeldExclusively(){
return getState() == 1;
}
//状态为0的时候,获取锁的方法
public boolean tryAcquire(int acquires) {
if(compareAndSetState(0,1)){
setExclusiveOwnerThread(Thread.currentThread());
return true;
}
return false;
}
//释放锁,将状态设置为0
protected boolean tryRelease(int arg) {
if(getState()==0){
throw new IllegalMonitorStateException();
}
setExclusiveOwnerThread(null);//移除占用线程的引用
setState(0);
return true;
}
Condition newCondition(){return new ConditionObject();}
}
//---以下是锁的具体实现,都是通过sync实现的---------
@Override
public void lock() {
sync.acquire(1);
}
@Override
public void lockInterruptibly() throws InterruptedException {
sync.acquireInterruptibly(1);
}
@Override
public boolean tryLock() {
return sync.tryAcquire(1);
}
@Override
public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException {
return sync.tryAcquireNanos(1,unit.toNanos(timeout));
}
@Override
public void unlock() {
sync.release(1);
}
@Override
public Condition newCondition() {
return sync.newCondition();
}
}
public class ThreadTest {
private int count;
private Mutex mutex = new Mutex();
@Test
public void addTest1(){
MyThread1 mt1 = new MyThread1("111");
MyThread1 mt2 = new MyThread1("222");
mt1.start();
mt2.start();
try {
mt1.join();
mt2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("addTest1 count = " + count);
}
@Test
public void addTest2(){
MyThread2 mt1 = new MyThread2();
MyThread2 mt2 = new MyThread2();
mt1.start();
mt2.start();
try {
mt1.join();
mt2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("addTest2 count = " + count);
}
class MyThread1 extends Thread{
private String name;
public MyThread1(String name){ this.name=name;}
@Override
public void run() {
for(int i=0;i<1000;i++){
count = count + 1;
}
}
}
class MyThread2 extends Thread{
@Override
public void run() {
for(int i=0;i<1000;i++){
mutex.lock();
try {
count = count + 1;
}catch (Exception e){
System.out.println("异常啦 ~ ~ " +e.getMessage());
}finally {
mutex.unlock();
}
}
}
}
}


队列同步器AbstractQueuedSynchronizer的更多相关文章
- Java 中队列同步器 AQS(AbstractQueuedSynchronizer)实现原理
前言 在 Java 中通过锁来控制多个线程对共享资源的访问,使用 Java 编程语言开发的朋友都知道,可以通过 synchronized 关键字来实现锁的功能,它可以隐式的获取锁,也就是说我们使用该关 ...
- java并发编程的艺术——第五章总结(Lock锁与队列同步器)
Lock锁 锁是用来控制多个线程访问共享资源的方式. 一般来说一个锁可以防止多个线程同时访问共享资源(但有些锁可以允许多个线程访问共享资源,如读写锁). 在Lock接口出现前,java使用synchr ...
- Java 显示锁 之 队列同步器AQS(六)
1.简述 锁时用来控制多个线程访问共享资源的方式,一般情况下,一个锁能够防止多个线程同时访问共享资源.但是有些锁可以允许多个线程并发的访问共享资源,比如读写锁. 在Java 5.0之前,在协调对共享对 ...
- AbstractQueuedSynchronizer 队列同步器源码分析
AbstractQueuedSynchronizer 队列同步器(AQS) 队列同步器 (AQS), 是用来构建锁或其他同步组件的基础框架,它通过使用 int 变量表示同步状态,通过内置的 FIFO ...
- Java中的队列同步器AQS
一.AQS概念 1.队列同步器是用来构建锁或者其他同步组件的基础框架,使用一个int型变量代表同步状态,通过内置的队列来完成线程的排队工作. 2.下面是JDK8文档中对于AQS的部分介绍 public ...
- [Java并发] AQS抽象队列同步器源码解析--锁获取过程
要深入了解java并发知识,AbstractQueuedSynchronizer(AQS)是必须要拿出来深入学习的,AQS可以说是贯穿了整个JUC并发包,例如ReentrantLock,CountDo ...
- AQS(抽象队列同步器)
AQS(全称为AbstractQueuedSynchronizer),即抽象队列同步器,它维护了一个volatile int state(代表共享资源)和一个FIFO线程等待队列. state的访问方 ...
- AQS(队列同步器)
目录导引: 一.简介 二.源码解析(JDK8) 三.运用示例 一.简介 1.volatile volatile修饰的共享变量可以保证可见性和有序性(禁止指令重排序). 2.CAS: CAS的原理很简单 ...
- java高并发核心类 AQS(Abstract Queued Synchronizer)抽象队列同步器
什么是AQS? 全称: Abstract Queued Synchronizer: 抽象队列同步器 是 java.util.concurrent.locks包下的一个抽象类 其编写者: Doug Le ...
随机推荐
- Tomcat与Web.xml配置
1.编码配置 <Connector acceptCount=”100″ connectionTimeout=”20000″ disableUploadTimeout=”true” enableL ...
- [原创]Java中使用File类的list方法获取一定数量的文件:FilenameFilter接口的特殊用法
前言:有时候我们可能会遇到这样一个问题:需要遍历一个包含极多文件的文件夹,首先想到的肯定是使用File.list()方法,该方法返回一个String[],但是如果文件达到几亿呢?这个时候我们就需要分批 ...
- 【kudu pk parquet】TPC-H Query2对比解析
这是[kudu pk parquet]的第二篇,query2在kudu和parquet上的对比解析,其中kudu包含有不能下发的谓词. 3台物理机,1T规模的数据集,impala和kudu版本是我们修 ...
- MVN package install error javac: invalid target release: 1.8
现象:---------------------------------[ERROR] Failure executing javac, but could not parse the error:j ...
- springboot项目部署运行(后台);端口被占用;
打包: mvn clean package -Pprod -Dmaven.test.skip=true -Pprod 使用生产环境配置: -DskipTests,不执行测试用例,但编译测试用例类生成相 ...
- Permission denied: .gvfs
$ sudo umount /home/william/.gvfs $ rm -rf ~/.gvfs/ Reference: (Permission denied: .gvfs)[https://an ...
- Nagios监控平台搭建及配置文件详解
Nagios是一款开源的免费网络监视工具,能有效监控Windows.Linux和Unix的主机状态,交换机路由器等网络设置,打印机等.在系统或服务状态异常时发出邮件或短信报警第一时间通知网站运维人员, ...
- 30 个 Java 集合面试问题及答案
30 个 Java 集合面试问题及答案 Java集合框架为Java编程语言的基础,也是Java面试中很重要的一个知识点.这里,我列出了一些关于Java集合的重要问题和答案. 1.Java集合框架是什么 ...
- 008 Android activity实现多个界面的相互跳转(主要利用Intent)
1.activity介绍 一个activity就把他理解成一个页面 2.新建activity流程 如图所示在com.lucky.test06的目录下,右击new--->Activity---&g ...
- LeetCode162.寻找峰值
162.寻找峰值 描述 峰值元素是指其值大于左右相邻值的元素. 给定一个输入数组 nums,其中 nums[i] ≠ nums[i+1],找到峰值元素并返回其索引. 数组可能包含多个峰值,在这种情况下 ...