JAVA面试——JAVA多线程并发(四)

简介: JAVA面试——JAVA多线程并发

4.1.24.什么是AQS 抽象的队列同步器

AbstractQueuedSynchronizer类如其名,抽象的队列式的同步器,AQS定义了一套多线程访问 共享资源的同步器框架,许多同步类实现都依赖于它,如常用的

ReentrantLock/Semaphore/CountDownLatch

image.png

它维护了一个volatile int state (代表共享资源)和一个FIFO线程等待队列(多线程争用资源被 阻塞时会进入此队列)。这里volatile是核心关键词,具体volatile的语义,在此不述。state的 访问方式有三种:

getState

setState()

compareAndSetState()

AQS定义两种资源共享方式

Exclusive 独占资源-ReentrantLock

Exclusive (独占,只有一个线程能执行,如ReentrantLock)

Share 共享资源Semaphore/CountDownLatch

Share (共享,多个线程可同时执行,如Semaphore/CountDownLatch)

AQS只是一个框架,具体资源的获取/释放方式交由自定义同步器去实现AQS这里只定义了一个 接口,具体资源的获取交由自定义同步器去实现了(通过state get/set/CAS)之所以没有定义成 abstract是因为独占模式下只用实现tryAcquire-tryRelease而共享模式下只用实现 tryAcquireShared-tryReleaseShared如果都定义成abstract那么每个模式也要去实现另一模 式下的接口。不同的自定义同步器争用共享资源的方式也不同。自定义同步器在实现时只需要实 现共享资源state的获取与释放方式即可,至于具体线程等待队列的维护(如获取资源失败入队/ 唤醒出队等),AQS已经在顶层实现好了。自定义同步器实现时主要实现以下几种方法:

1. isHeldExclusivelyO该线程是否正在独占资源。只有用到condition才需要去实现它。

2. tryAcquire(int):独占方式。尝试获取资源,成功则返回true失败则返回false

3. tryRelease(int):独占方式。尝试释放资源,成功则返回true,失败则返回false

4. tryAcquireShared(int):共享方式。尝试获取资源。负数表示失败;0表示成功,但没有剩余 可用资源;正数表示成功,且有剩余资源。

5. tryReleaseShared(int):共享方式。尝试释放资源,如果释放后允许唤醒后续等待结点返回 true否则返回false

同步器的实现是ABS 核心 (state资源状态计数)

同步器的实现是ABS核心,以ReentrantLock为例,state初始化为0,表示未锁定状态。A线程 lock时,会调用tryAcquire()独占该锁并将state+1此后,其他线程再tryAcquire()时就会失 败,直到A线程unlock()state=0 (即释放锁)为止,其它线程才有机会获取该锁。当然,释放 锁之前,A线程自己是可以重复获取此锁的(state会累加),这就是可重入的概念。但要注意, 获取多少次就要释放多么次,这样才能保证state是能回到零态的。

CountDownLatch以例,任务分为N个子线程去执行,state也初始化为N (注意N要与 线程个数一致)。这N个子线程是并行执行的,每个子线程执行完后countDown一次,state CAS1。等到所有子线程都执行完后(即state=0)unpark()主调用线程,然后主调用线程 就会从await()函数返回,继续后余动作。

ReentrantReadWriteLock实现独占和共享两种方式

一般来说,自定义同步器要么是独占方法,要么是共享方式,他们也只需实现tryAcquire- tryReleasetryAcquireShared-tryReleaseShared 中的一种即可。AQS 也支持自定义同步器 同时实现独占和共享两种方式,如ReentrantReadWriteLock

目录
相关文章
|
7天前
|
安全
List并发线程安全问题
【10月更文挑战第21天】`List` 并发线程安全问题是多线程编程中一个非常重要的问题,需要我们认真对待和处理。只有通过不断地学习和实践,我们才能更好地掌握多线程编程的技巧和方法,提高程序的性能和稳定性。
|
4天前
|
缓存 Java 调度
Java中的多线程编程:从基础到实践
【10月更文挑战第24天】 本文旨在为读者提供一个关于Java多线程编程的全面指南。我们将从多线程的基本概念开始,逐步深入到Java中实现多线程的方法,包括继承Thread类、实现Runnable接口以及使用Executor框架。此外,我们还将探讨多线程编程中的常见问题和最佳实践,帮助读者在实际项目中更好地应用多线程技术。
11 3
|
5天前
|
监控 安全 Java
Java多线程编程的艺术与实践
【10月更文挑战第22天】 在现代软件开发中,多线程编程是一项不可或缺的技能。本文将深入探讨Java多线程编程的核心概念、常见问题以及最佳实践,帮助开发者掌握这一强大的工具。我们将从基础概念入手,逐步深入到高级主题,包括线程的创建与管理、同步机制、线程池的使用等。通过实际案例分析,本文旨在提供一种系统化的学习方法,使读者能够在实际项目中灵活运用多线程技术。
|
4天前
|
缓存 安全 Java
Java中的多线程编程:从基础到实践
【10月更文挑战第24天】 本文将深入探讨Java中的多线程编程,包括其基本原理、实现方式以及常见问题。我们将从简单的线程创建开始,逐步深入了解线程的生命周期、同步机制、并发工具类等高级主题。通过实际案例和代码示例,帮助读者掌握多线程编程的核心概念和技术,提高程序的性能和可靠性。
8 2
|
4天前
|
Java
Java中的多线程编程:从基础到实践
本文深入探讨Java多线程编程,首先介绍多线程的基本概念和重要性,接着详细讲解如何在Java中创建和管理线程,最后通过实例演示多线程的实际应用。文章旨在帮助读者理解多线程的核心原理,掌握基本的多线程操作,并能够在实际项目中灵活运用多线程技术。
|
6天前
|
Java 数据处理 开发者
Java多线程编程的艺术:从入门到精通####
【10月更文挑战第21天】 本文将深入探讨Java多线程编程的核心概念,通过生动实例和实用技巧,引导读者从基础认知迈向高效并发编程的殿堂。我们将一起揭开线程管理的神秘面纱,掌握同步机制的精髓,并学习如何在实际项目中灵活运用这些知识,以提升应用性能与响应速度。 ####
23 3
|
8天前
|
存储 Java 程序员
Java面试加分点!一文读懂HashMap底层实现与扩容机制
本文详细解析了Java中经典的HashMap数据结构,包括其底层实现、扩容机制、put和查找过程、哈希函数以及JDK 1.7与1.8的差异。通过数组、链表和红黑树的组合,HashMap实现了高效的键值对存储与检索。文章还介绍了HashMap在不同版本中的优化,帮助读者更好地理解和应用这一重要工具。
25 5
|
7天前
|
Java
Java中的多线程编程:从入门到精通
本文将带你深入了解Java中的多线程编程。我们将从基础概念开始,逐步深入探讨线程的创建、启动、同步和通信等关键知识点。通过阅读本文,你将能够掌握Java多线程编程的基本技能,为进一步学习和应用打下坚实的基础。
|
7天前
|
存储 Java
[Java]面试官:你对异常处理了解多少,例如,finally中可以有return吗?
本文介绍了Java中`try...catch...finally`语句的使用细节及返回值问题,并探讨了JDK1.7引入的`try...with...resources`新特性,强调了异常处理机制及资源自动关闭的优势。
14 1
|
8天前
|
Java 开发者
在Java多线程编程中,选择合适的线程创建方法至关重要
【10月更文挑战第20天】在Java多线程编程中,选择合适的线程创建方法至关重要。本文通过案例分析,探讨了继承Thread类和实现Runnable接口两种方法的优缺点及适用场景,帮助开发者做出明智的选择。
9 2