队列同步器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 ...
随机推荐
- android 多点触控
多点触控 1.多点触控从字面意思讲就是你用大于等于2根的手指触摸子啊手机屏幕上. Android中监听触摸事件是onTouchEvent方法,它的参数为MotionEvent,下面列举MotionEv ...
- Redis 一个很诡异的问题(部署)
使用Redis并用window服务的方式 运行时.突然报错 在启动进程意外中止 解决方案: 调试了很久 发现居然是在 Logfile的配置中的问题. 错误的logfile logfile " ...
- Topshelf + Quartz2.5 创建基于windows服务
1.创建一个定时调度Quartz类 using Quartz; using Quartz.Impl; using System; using System.Collections.Generic; u ...
- 解决在cmder中bash(WSL)上下箭头不能使用问题
有三种解决方式,第一种方式最简单实用 安装新版本wslbridge 这个解决方法最简单,最实用,下载第三方wslbridge,安装即可使用. 这时再进入cmder,运行bash.exe,可以发现上下左 ...
- 严选 Android 路由框架优化(下篇)
3 router 框架优化 3.1 apt 生成代码量过大问题优化 思考框架本身,其实可以发现仅有 router 映射表是需要根据注解编译生成的,其他的全部代码都是固定代码,完全可以 sdk 中直接编 ...
- Tensorflow报错:InvalidArgumentError: You must feed a value for placeholder tensor 'input_y' with dtype
此错误神奇之处是每次第一次运行不会报错,第二次.第三次第四次....就都报错了.关掉重启,又不报错了,运行完再运行一次立马报错!搞笑! 折磨了我半天,终于被我给解决了! 问题解决来源于这边博客:htt ...
- day08.1-Linux软件包管理
Linux系统中的两种软件包:tar,保存内容为源码,编译后再安装:rpm,保存内容为编译后的机器码,直接安装.其中,rpm软件包由5部分构成,分别为: 第1部分是name,表示这个rpm软件包的名称 ...
- JDK、JRE、JVM三者关系
一.JDK.JRE.JVM三者的关系 JDK包含了JRE和JVM,JRE包含了JVM,其中JRE中没有javac 附一张官网的详细图: 二.RIA RIA(富客户端):能完成浏览器无法完成的功能,它是 ...
- docker容器管理及网络管理
防火墙规则—— INPUT 主要用于主机防火墙,设置规则屏蔽处理进入本机的数据包示例:禁止10.180.100.141这个机器访问我本机的web服务iptables -t filter -A INPU ...
- 从HDU1004来看C++<map>
最近做题有点浮躁~于是从HDU第一题开始刷,刷到1004题的时候突发奇想来复习一发很久没有用到过的map 题意是给你n个气球,每个气球有一种颜色,让你求出数量最多的气球颜色 因为颜色是气球数量的识别关 ...