AQS是JUC中很多同步组件的构建基础,简单来讲,它内部实现主要是状态变量state和一个FIFO队列来完成,同步队列的头结点是当前获取到同步状态的结点,获取同步状态state失败的线程,会被构造成一个结点(或共享式或独占式)加入到同步队列尾部(采用自旋CAS来保证此操作的线程安全),随后线程会阻塞;释放时唤醒头结点的后继结点,使其加入对同步状态的争夺中。

  AQS为我们定义好了顶层的处理实现逻辑,我们在使用AQS构建符合我们需求的同步组件时,只需重写tryAcquire,tryAcquireShared,tryRelease,tryReleaseShared几个方法,来决定同步状态的释放和获取即可,至于背后复杂的线程排队,线程阻塞/唤醒,如何保证线程安全,都由AQS为我们完成了,这也是非常典型的模板方法的应用。AQS定义好顶级逻辑的骨架,并提取出公用的线程入队列/出队列,阻塞/唤醒等一系列复杂逻辑的实现,将部分简单的可由使用者决定的操作逻辑延迟到子类中去实现。

package com.abstractqueuesynchronizer;

import java.util.concurrent.locks.AbstractQueuedSynchronizer;

public class SelfAbstractQueueSynchronizer {

    //继承AbstractQueuedSynchronizer类
private static class Syn extends AbstractQueuedSynchronizer { private static final long serialVersionUID = 1L; //是否拥有锁
protected boolean isHeldExclusively() {
return getState() == 1;
} //获取锁
public boolean tryAcquire(int acquires) {
if(compareAndSetState(0, 1)) {
setExclusiveOwnerThread(Thread.currentThread());
return true;
}
return false;
} //释放所
protected boolean tryRelease(int releases) {
if(getState() == 0)
throw new IllegalMonitorStateException();
setExclusiveOwnerThread(null);
setState(0);
return true;
}
} private final Syn syn = new Syn(); public void lock() {
syn.acquire(1);
} public boolean tryLock() {
return syn.tryAcquire(1);
} public void unlock() {
syn.release(1);
} public boolean isLocked() {
return syn.isHeldExclusively();
}
}

测试

package com.abstractqueuesynchronizer;

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier; public class Main { private static CyclicBarrier barrier = new CyclicBarrier(31);
private static int a = 0;
private static SelfAbstractQueueSynchronizer test = new SelfAbstractQueueSynchronizer(); public static void main(String[] args) throws InterruptedException, BrokenBarrierException { for(int i = 0; i < 30; i++) {
Thread t = new Thread(new Runnable(){ @Override
public void run() {
for(int i = 0; i < 1000; i++) {
unlockIncrement();
}
try {
barrier.await();
} catch (Exception e) {
e.printStackTrace();;
}
} });
t.start();
} barrier.await();
System.out.println("unlock model a= " + a); System.out.println("##########################"); barrier.reset();
a = 0;
for(int i = 0; i < 30; i++) {
Thread t = new Thread(new Runnable(){
@Override
public void run() {
for(int i = 0; i < 1000; i++ ) {
lockIncrement();
} try {
barrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
} });
t.start();
} barrier.await();
System.out.println("lock model a= " + a); } public static void unlockIncrement() {
a++;
} public static void lockIncrement() {
test.lock();
a++;
test.unlock();
} }

AbstractQueuedSynchronizer简单使用的更多相关文章

  1. JUC锁框架_AbstractQueuedSynchronizer详细分析

      AQS是JUC锁框架中最重要的类,通过它来实现独占锁和共享锁的.本章是对AbstractQueuedSynchronizer源码的完全解析,分为四个部分介绍: CLH队列即同步队列:储存着所有等待 ...

  2. AbstractQueuedSynchronizer的简单分析

    说明:本作者是文章的原创作者,转载请注明出处:本文地址:http://www.cnblogs.com/qm-article/p/7955781.html 一.AbstractQueuedSynchro ...

  3. AbstractQueuedSynchronizer的简单介绍

    AbstractQueuedSynchronizer简称为AQS.大多数开发者不会直接使用AQS,标准同步器类的集合能够满足绝大多数情况的需求. 1.AbstractQueuedSynchronize ...

  4. Java并发基础框架AbstractQueuedSynchronizer初探(ReentrantLock的实现分析)

    AbstractQueuedSynchronizer是实现Java并发类库的一个基础框架,Java中的各种锁(RenentrantLock, ReentrantReadWriteLock)以及同步工具 ...

  5. 并发编程 20—— AbstractQueuedSynchronizer 深入分析

    Java并发编程实践 目录 并发编程 01—— ThreadLocal 并发编程 02—— ConcurrentHashMap 并发编程 03—— 阻塞队列和生产者-消费者模式 并发编程 04—— 闭 ...

  6. Java Concurrent之 AbstractQueuedSynchronizer

    ReentrantLock/CountDownLatch/Semaphore/FutureTask/ThreadPoolExecutor的源码中都会包含一个静态的内部类Sync,它继承了Abstrac ...

  7. Java并发包源码学习之AQS框架(四)AbstractQueuedSynchronizer源码分析

    经过前面几篇文章的铺垫,今天我们终于要看看AQS的庐山真面目了,建议第一次看AbstractQueuedSynchronizer 类源码的朋友可以先看下我前面几篇文章: <Java并发包源码学习 ...

  8. 通过ReentrantLock源代码分析AbstractQueuedSynchronizer独占模式

    1. 重入锁的概念与作用       reentrant 锁意味着什么呢?简单来说,它有一个与获取锁相关的计数器,如果已占有锁的某个线程再次获取锁,那么lock方法中将计数器就加1后就会立刻返回.当释 ...

  9. 从一个简单的Java单例示例谈谈并发

    一个简单的单例示例 单例模式可能是大家经常接触和使用的一个设计模式,你可能会这么写 public class UnsafeLazyInitiallization { private static Un ...

随机推荐

  1. Reporting Services 配置工具

    使用 Reporting Services 配置管理器可配置 Reporting Services 安装.如果使用“仅文件”选项安装报表服务器,则必须使用此工具来配置服务器,才能使用该服务器.如果使用 ...

  2. js 通过浏览器直接打开应用程序(IOS,Android)

    实现效果 如下图所示,在手机浏览器中访问京东的手机版网站(m.jd.com),顶部会有一个广告图,点击这个广告图,如果手机上已经安装了京东App,则直接打开,如果没有安装,则开始下载. 实现方式 1. ...

  3. Linux shell 归纳之 cp

    1. 复制文件夹folder1(包括所有子文件夹和文件), 并命名为folder2 # cp -r /usr/folder1 folder2 2. 复制文件file1 到它的上一级的目录的abc文件夹 ...

  4. MySQL5.6多实例安装

    MySQL-5.6.36.tar.gz多实例安装 查看官方安装说明 more INSTALL-SOURCE 安装cmake及相关依赖包 yum install -y cmake gcc [root@v ...

  5. centos7安装MongoDB4.0(yum安装)

    1.添加 yum repo vi /etc/yum.repos.d/mongodb-org-4.0.repo 添加如下内容 [mongodb-org-4.0] name=MongoDB Reposit ...

  6. day08—css布局解决方案之多列布局

    转行学开发,代码100天——2018-03-24 本文将记录CSS布局之垂直布局解决方案. 常见的多列布局包括以下: 1.定宽+自适应 2.两列定宽+一列自适应 3.不定宽+自适应 4.两列不定宽+一 ...

  7. sticky用法

    可以用于滚动到一定距离以后让他实现定位效果. 比如滚动到50px的时候让导航栏固定定位. 用法:给最外层的div设置绝对定位 然后要固定的div设置position:sticky; top:0: 这样 ...

  8. bash 特殊符号的含义

    bash常见特殊符号及含义 linux中shell变量的含义解释

  9. HTTP权威指南-学习笔记

    目录 HTTP权威指南-学习笔记 HTTP: Web的基础 URL与资源 HTTP报文 连接管理 HTTP结构 Web服务器 代理 缓存 集成点: 网关,隧道及中继 Web机器人 识别,认证与安全 客 ...

  10. opencv部署服务器报错

    报错内容: ImportError: libSM.so.6: cannot open shared object file: No such file or directory 解决办法: sudo ...