iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > Python >Java利用AQS实现自定义锁
  • 208
分享到

Java利用AQS实现自定义锁

2024-04-02 19:04:59 208人浏览 安东尼

Python 官方文档:入门教程 => 点击学习

摘要

目录什么是AQSAQS原理利用AQS实现自定义锁一:首先创建一个类实现Lock接口,它有6个方法需要实现二:创建一个内部类,继承AbstractQueuedSynchronizer三

什么是AQS

AQS(AbstractQueuedSynchronizer),中文名抽象队列同步器

AQS定义了一套多线程访问共享资源的同步器框架,主要用来自定义锁和同步器

AQS原理

AQS 核心思想:

  • 如果被请求的共享资源空闲,则将当前请求资源的线程设置为有效的工作线程,并且将共享资源设置为锁定状态。
  • 如果被请求的共享资源被占用,将暂时获取不到锁的线程加入到阻塞队列中,等待被唤醒和锁的分配

实现核心思想的的队列:CLH队列

CLH队列是一个虚拟的双向队列,AQS 是将每条请求共享资源的线程封装成一个 CLH 锁队列的一个结点(node)来实现锁的分配。

共享资源用 volatile 关键词修饰,保证线程间的可见性

   
    private volatile int state;

0状态表示空闲,1状态或以上表示不空闲

共享资源(state)的访问方式有三种:  

  1. getState()   获得共享资源状态
  2. setState()   设置共享资源状态
  3. compareAndSetState() 更改共享资源状态(底层unsafe类)

 源代码如下

    
    protected final int getState() {
        return state;
    }
 
    
    protected final void setState(int newState) {
        state = newState;
    }
    
    protected final boolean compareAndSetState(int expect, int update) {
        // See below for intrinsics setup to support this
        return unsafe.compareAndSwapint(this, stateOffset, expect, update);
    }

利用AQS实现自定义锁

一:首先创建一个类实现Lock接口,它有6个方法需要实现

  • lock():加锁(不成功进入阻塞队列等待)
  • lockInterruptibly():是否加锁可打断
  • tryLock()://加锁(不成功不会进入阻塞队列等待,可以去做其他事情)
  • tryLock(long time,TimeUnit unit):加锁(规定时间内未获得则放弃加锁)
  • unlock():释放锁
  • newCondition():创建条件变量

二:创建一个内部类,继承AbstractQueuedSynchronizer

可以根据需求重写具体方法,总共有5种方法

  • isHeldExclusively():该线程是否正在独占资源。只有用到condition才需要去实现它。
  • tryAcquire(int):独占方式。尝试获取资源,成功则返回true,失败则返回false。
  • tryRelease(int):独占方式。尝试释放资源,成功则返回true,失败则返回false。
  • tryAcquireShared(int):共享方式。尝试获取资源。负数表示失败;0表示成功,但没有剩余可用资源;正数表示成功,且有剩余资源。
  • tryReleaseShared(int):共享方式。尝试释放资源,如果释放后允许唤醒后续等待结点返回true,否则返回false。

三:我需要自定义一个独占锁不可重入具有变量条件的锁

分析

  • 独占锁:AQS同步器中需要重写独占方式的获取资源tryAcquire(int)和释放资源tryRelease(int)方法
  • 不可重入:AQS同步器需要实现isHeldExclusively():
  • 具有条件变量:AQS同步器中 return new ConditionObject();

具体代码如下

//自定义锁(不可重入)(独占锁)(条件变量)
class MyLock implements Lock{
    //内部类,AQS同步器类
    class MySync extends AbstractQueuedSynchronizer{
        @Override
        protected boolean tryAcquire(int arg) {
            if (compareAndSetState(0,1)){
                System.out.println("获得锁成功");
                //加上了锁,并设置owner为当前线程
                setExclusiveOwnerThread(Thread.currentThread());
                return true;
            }
            System.out.println("获得锁失败");
            return false;
        }
 
        @Override
        protected boolean tryRelease(int arg) {
            setExclusiveOwnerThread(null);
            setState(0);
            return true;
        }
 
        @Override
        protected boolean isHeldExclusively() {
            return getState() == 1;
        }
 
        public Condition newCondition(){
            return new ConditionObject();
        }
    }
 
    private MySync mySync = new MySync();
 
    @Override //加锁(不成功进入阻塞队列等待)
    public void lock() {
        mySync.acquire(1);
    }
 
    @Override //加锁可打断
    public void lockInterruptibly() throws InterruptedException {
        mySync.acquireInterruptibly(1);
    }
 
    @Override //加锁(不成功不会进入阻塞队列等待,可以去做其他事情)
    public boolean tryLock() {
        return mySync.tryAcquire(1);
    }
 
    @Override //尝试加锁 带时间
    public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
        return mySync.tryAcquireNanos(1,unit.toNanos(time));
    }
 
    @Override //释放锁
    public void unlock() {
        mySync.release(1);
    }
 
    @Override //创建条件变量
    public Condition newCondition() {
        return mySync.newCondition();
    }
}

到此这篇关于Java利用AQS实现自定义锁的文章就介绍到这了,更多相关Java AQS实现自定义锁内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: Java利用AQS实现自定义锁

本文链接: https://www.lsjlt.com/news/165180.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Java利用AQS实现自定义锁
    目录什么是AQSAQS原理利用AQS实现自定义锁一:首先创建一个类实现Lock接口,它有6个方法需要实现二:创建一个内部类,继承AbstractQueuedSynchronizer三...
    99+
    2024-04-02
  • 怎么在Java中利用AQS实现一个自定义同步器
    这篇文章主要为大家详细介绍了怎么在Java中利用AQS实现一个自定义同步器,文中示例代码介绍的非常详细,具有一定的参考价值,发现的小伙伴们可以参考一下:Java的特点有哪些Java的特点有哪些1.Java语言作为静态面向对象编程语言的代表,...
    99+
    2023-06-06
  • Java利用自定义注解实现数据校验
    目录JSR303介绍引入依赖常用注解开启校验数据校验测试自定义的封装错误信息统一异常处理分组校验创建分组校验接口添加校验注解开启分组校验自定义校验编写自定义的校验注解编写自定义的校验...
    99+
    2024-04-02
  • WPF利用WindowChrome实现自定义窗口
    目录简介效果图自定义最小化、最大化、关闭按钮布局实现结语简介 Microsoft官网关于 WindowChome 的介绍 截取Microsoft文章的一段话: 若要在保留其标准功能时...
    99+
    2023-02-16
    WPF WindowChrome自定义窗口 WPF 自定义窗口 WPF WindowChrome
  • 利用Python实现自定义连点器
    目录前言整体思路所有功能简单演示点击功能延时功能连点功能存储功能读取功能存储导入功能【升级版】拖拽功能右击、中击、双击功能的实现按键功能滚动滚轮功能查看功能执行功能逻辑判断功能板块判...
    99+
    2024-04-02
  • Java利用自定义注解、反射实现简单BaseDao实例
    在常见的ORM框架中,大都提供了使用注解方式来实现entity与数据库的映射,这里简单地使用自定义注解与反射来生成可执行的sql语句。这是整体的目录结构,本来是为复习注解建立的项目^.^好的,首先我们来确定思路。1. 自定义@Table @...
    99+
    2023-05-31
    java 自定义注解 反射
  • 使用自定义注解实现redisson分布式锁
    目录自定义注解实现redisson分布式锁自定义注解aop解析注解service中使用注解加锁使用redisson分布式锁应用应用场景Redisson管理类分布式锁测试类自定义注解实...
    99+
    2024-04-02
  • 怎么利用Python实现自定义连点器
    前言前些天留意到我妈一直在预约四价疫苗都约不上,就想着写个程序来模拟人的操作去点击,判断疫苗是否被抢完,无限循环去刷新这个页面,一旦疫苗可预约就立马抢下来选择时间接种人。当预约成功后就语音循环播报:已经抢到,赶紧过来看一下。基于以上的想法和...
    99+
    2023-05-14
    Python
  • Angular怎么利用service实现自定义服务
    这篇文章主要介绍“Angular怎么利用service实现自定义服务”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Angular怎么利用service实现自定义服务...
    99+
    2024-04-02
  • Feign利用自定义注解实现路径转义详解
    目录背景解决方案最后背景 近期由于项目中需要,所以需要通过Feign封装一个对Harbor操作的sdk信息。 在调用的过程中发现,当请求参数中带有"/"时,Fei...
    99+
    2024-04-02
  • Feign怎么利用自定义注解实现路径转义
    本篇内容主要讲解“Feign怎么利用自定义注解实现路径转义”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Feign怎么利用自定义注解实现路径转义”吧!背景近期由于项目中需要,所以需要通过Feig...
    99+
    2023-07-02
  • Android自定义view实现滑动解锁效果
    本文实例为大家分享了Android自定义view实现滑动解锁的具体代码,供大家参考,具体内容如下 1. 需求如下: 近期需要做一个类似屏幕滑动解锁的功能,右划开始,左划暂停。 2. ...
    99+
    2024-04-02
  • Android自定义控件实现九宫格解锁
    关于九宫格解锁,我看了不少博客,但是都感觉很复杂,可能我的功夫还不到,所以很多东西我不了解,但是我还是打算写一个自己的九宫格。我相信我的九宫格大家都能很快的理解,当然如果需要实现更复...
    99+
    2024-04-02
  • 利用Android实现比较炫酷的自定义View
    目录一、背景1.1、控件效果1.2、从功能上分析一下这个控件,大致有以下特点1.3、从结构上分析二、 背景圆实现2.1、实现粒子运动2.2、实现渐变色圆2.3、展示背景圆的扇形区域2...
    99+
    2024-04-02
  • SpringBoot利用自定义注解实现多数据源
    目录前置学习数据准备行动起来前置学习 需要了解 注解、Aop、SpringBoot整合Mybatis的使用。 数据准备 基础项目代码:https://gitee.com/J_look...
    99+
    2022-11-13
    SpringBoot 自定义注解 多数据源 SpringBoot多数据源
  • Flask如何利用自定义接口实现mock应用
    这篇文章主要介绍了Flask如何利用自定义接口实现mock应用的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Flask如何利用自定义接口实现mock应用文章都会有所收获,下面我们一起来看看吧。问题:后端接口已提...
    99+
    2023-07-05
  • Flask利用自定义接口实现mock应用详解
    问题:后端接口已提供,前端需要依赖后端接口返回的数据进行前端页面的开发,如何配合前端? mock接口 flask自定义接口实现查询接口:查询全部、部分查询 具体看下面的代码: #导入...
    99+
    2023-03-06
    Flask自定义接口实现mock Flask自定义接口mock Flask mock
  • Android自定义view利用PathEffect实现动态效果
    目录前言一、首先介绍下PathEffect的一些子类二、看看子类具体的一些代码三、案例实现(CornerPathEffect,PathDashPathEffect,ComposePa...
    99+
    2024-04-02
  • 使用Java如何实现异常自定义
    今天就跟大家聊聊有关使用Java如何实现异常自定义,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。具体代码如下所示: class ChushulingException ext...
    99+
    2023-05-31
    java 自定义异常 ava
  • Java SpringMVC实现自定义拦截器
    目录SpringMVC实现自定义拦截器1 拦截器(interceptor)的作用2 拦截器和过滤器区别3.实现过程3.1创建拦截器类实现HandlerInterceptor接口3.2...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作