java同步器AQS架构AbstractQueuedSynchronizer原理解析

yizhihongxing

Java同步器AQS架构AbstractQueuedSynchronizer原理解析

什么是AQS?

抽象队列同步器(AbstractQueuedSynchronizer,AQS)是Java中一种同步工具,它是构建锁与同步器的框架,是并发包中用来构造锁、信号量、倒计数器、线程池等等使用的开发工具类。它采用了一种FIFO的队列等待机制来保证线程执行的顺序。

AQS的核心思想

AQS的核心思想是,如果被请求的共享资源空闲,则将当前请求资源的线程设置为有效的工作线程,并且将共享资源设置为锁定状态。如果共享资源被占用,那么就需要一套线程阻塞等待以及被唤醒时锁分配的机制,这个机制AQS是通过内部的FIFO队列来实现的。

AQS的核心组成

在AQS中,派生类需要实现以下方法:

  1. isHeldExclusively()
  2. tryAcquire(int)
  3. tryRelease(int)

其中isHeldExclusively()方法判断当前线程是否保持独占模式,只有用到 ReentrantLock 中的 Condition 才需要这个功能。

tryAcquire(int)方法是独占模式下的资源申请。在独占模式下,当拿不到这把锁的时候会将当前线程唤醒,添加到队列中。

tryRelease(int)方法是独占模式下的释放资源。

如何使用AQS

ReentrantLock 为例,演示如何使用AQS。

示例1:简单的 ReentrantLock 使用示例

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class ReentrantLockDemo {

    private static Lock lock = new ReentrantLock();

    public static void main(String[] args) {
        for (int i = 0; i < 5; i++) {
            new Thread(new Runnable() {
                public void run() {
                    lock.lock();
                    try {
                        System.out.println(Thread.currentThread().getName() + "获得了锁");
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } finally {
                        System.out.println(Thread.currentThread().getName() + "释放了锁");
                        lock.unlock();
                    }
                }
            }).start();
        }
    }
}

示例代码中,我们定义了一个 ReentrantLock 对象,然后在一个 for 循环中创建了5个线程,每个线程获取锁、睡眠 500 毫秒进入阻塞状态,然后释放锁。

示例2:Lock 结合 Condition 示例

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class LockConditionDemo {

    private static Lock lock = new ReentrantLock();
    private static Condition condition = lock.newCondition();

    public static void main(String[] args) {
        new Thread(new Runnable() {
            public void run() {
                try {
                    lock.lock();
                    System.out.println(Thread.currentThread().getName() + "等待信号");
                    condition.await();
                    System.out.println(Thread.currentThread().getName() + "收到信号");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    lock.unlock();
                }
            }
        }).start();

        new Thread(new Runnable() {
            public void run() {
                lock.lock();
                System.out.println(Thread.currentThread().getName() + "发出信号通知");
                condition.signalAll();
                lock.unlock();
            }
        }).start();
    }
}

示例代码中,我们定义了一个 ReentrantLock 对象以及一个 Condition 对象,生产者线程发出一个信号通知,然后唤醒等待信号的消费者线程,消费者线程接收到要求后,执行最后的代码逻辑。

总结

通过上面的例子,我们初步了解到了什么是AQS,其核心思想和组成部分,以及如何使用 ReentrantLockCondition 针对 AQS 进行对锁与同步器进行控制的实现方式。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:java同步器AQS架构AbstractQueuedSynchronizer原理解析 - Python技术站

(0)
上一篇 2023年6月26日
下一篇 2023年6月26日

相关文章

  • 如何在 Illustrator 中设置文字格式?ai字体设置

    如何在 Illustrator 中设置文字格式 在 Adobe Illustrator 中,你可以使用以下步骤设置文字的格式和字体。 步骤 1:选择文字工具 首先,选择左侧工具栏中的“文字工具”(T)。 步骤 2:选择文本框 点击画布上的位置,创建一个文本框。你可以拖动文本框的边缘来调整大小。 步骤 3:输入文本 在文本框中输入你想要的文字内容。 步骤 4:…

    other 2023年8月18日
    00
  • Java中线程Thread的三种方式和对比

    Java中线程Thread的三种方式和对比攻略 Java中线程Thread的方式可以大致分为三类,分别是继承Thread类、实现Runnable接口和使用Callable和Future接口配合使用。下面将一一介绍它们的特点和使用场景。 继承Thread类 继承Thread类是最简单直接的创建线程的方式,只需要创建一个类继承Thread类并重写run()方法即…

    other 2023年6月27日
    00
  • android实现图片闪烁动画效果的两种实现方式(实用性高)

    当使用Android开发时,可以使用两种方式实现图片闪烁动画效果。下面将详细介绍这两种实现方式,并提供两个示例说明。 方式一:使用透明度动画 首先,在XML布局文件中添加一个ImageView来显示图片: <ImageView android:id=\"@+id/imageView\" android:layout_width=\&…

    other 2023年9月7日
    00
  • 关于PHP中Object对象的笔记分享

    关于PHP中Object对象的笔记分享 1. 什么是PHP中的Object对象? 在PHP中,Object对象是指通过类实例化的对象。它是一个可以存储数据和方法的实体,可以根据其类的定义进行操作和访问。 2. 如何创建Object对象? 要创建一个Object对象,首先需要定义一个类。类是对象的模板,描述了对象的属性和方法。下面是一个示例的类定义: clas…

    other 2023年6月28日
    00
  • C++ 数据结构完全二叉树的判断

    关于 C++ 数据结构完全二叉树的判断,具体的步骤如下: 1. 引言 存储结构一般有顺序存储和链式存储两种方式,但是对于完全二叉树来说,最适合的存储结构就是顺序存储结构,因为完全二叉树的空节点数是比较容易计算出来的,可以通过计算来避免节省内存空间,并且完全二叉树还可以通过下标来计算某个节点的父节点和子节点的下标。 完全二叉树的性质就是:除最后一层节点外,其它…

    other 2023年6月27日
    00
  • thymeleaf实现th:each双重多重嵌套功能

    Thymeleaf实现th:each双重多重嵌套功能攻略 Thymeleaf是一种用于在Web应用程序中创建动态内容的模板引擎。它提供了强大的功能,包括th:each指令,可以用于在模板中进行循环迭代。本攻略将详细介绍如何使用Thymeleaf的th:each指令实现双重多重嵌套功能。 1. 基本语法 在Thymeleaf中,th:each指令用于迭代集合或…

    other 2023年7月28日
    00
  • php开源项目大全

    以下是“PHP开源项目大全”的完整攻略,过程中包含两个示例说明的标准格式文本: PHP开源项目大全 PHP是一种流行的服务器端脚本语言,有许多优秀的开源项目可供使用。本文将介绍如何查找和使用PHP开源项目。 1. 查找PHP开源项目 可以通过以下方式查找PHP开源项目: 在GitHub上搜索“PHP”关键字。 在SourceForge上搜索“PHP”关键字。…

    other 2023年5月10日
    00
  • win7 C盘空间缩水的有效处理方法

    Win7 C盘空间缩水的有效处理方法攻略 1. 清理临时文件和回收站 首先,我们可以清理掉一些不必要的临时文件和回收站中的文件,以释放一些空间。以下是具体步骤: 打开“开始”菜单,点击“计算机”。 右键点击C盘,选择“属性”。 在“常规”选项卡下,点击“清理磁盘”。 系统会扫描磁盘并列出可以清理的文件类型。 勾选“临时文件”和“回收站”选项,并点击“确定”进…

    other 2023年8月1日
    00
合作推广
合作推广
分享本页
返回顶部