LockSupport和AbstractQueuedSynchronizer有哪些实际用例?

13

各位,能否给一个简单的实际示例说明LockSupportAbstractQueuedSynchronizer的用法?在Javadoc中给出的示例相当繁琐。

Semaphore许可的使用对我来说是明确的。

感谢任何回应。

5个回答

15
如果您谈论使用锁定机制(甚至同步屏障),只需使用 java.util.concurrent.Lock。明显的建议是使用ReentrantLock,它委托给一个 Synch。 Synch 是 AQS,而 AQS 再次使用 LockSupport
它们都是在幕后为您完成的。
编辑:
现在让我们来看看 AbstractQueuedSynchronizer(AQS)的实际用途。
虽然并发结构在使用上可能非常不同,但它们可以具有相同的基本功能。
例如,在某些条件下挂起此线程。 在其他某些条件下唤醒线程。
这是一组非常广泛的指令,但它表明大多数并发结构都需要一些共同的功能,能够为它们处理这些操作。 这就是 AQS 的作用。 有五个主要的同步屏障。
- ReentrantLock - ReadLock - WriteLock - Semaphore - CountDownLatch 现在,所有这五种结构在使用时都有非常不同的规则。 CountdownLatch 可以允许多个线程同时运行,但会强制一个或多个线程等待,直到至少n个线程在该门闩上计数。 ReentrantLock 只强制一个线程进入关键节,而将所有其他线程排队等待其完成。 ReadLock 允许任意数量的读取线程进入关键节,直到获得写锁。
示例可以继续进行,但总体来说,它们都使用 AQS。 这是因为它们能够使用 AQS 提供的原始功能,并在其上实现更复杂的功能。 AQS 允许您停放未停放和唤醒线程(必要时可以中断),以支持许多复杂的功能。

W.:我看到 AbstractQueuedLongSynchronizer 中使用了 LockSupport,你认为它是一种内部 API 类吗?我想看看有关它的任何说明性代码... - Max
2
@Max LockSupport是一个任何人都可以使用的实用程序类。它不一定是内部类Unsafe.java是内部类的一个很好的例子。LockSupport是公共的,这样其他人就可以编写自己的AQS版本。 - John Vint
谢谢John,我知道这是为了扩展。你的回答让我重新提出一个问题:对我来说,通常使用AbstractQueuedSynchronizer似乎不太清楚。 - Max

1

它们并不适用于客户端代码的直接使用,更多地是为了帮助构建新的并发类。


1
AQS是一个非常棒的用于构建并发原语的类 - 但它很复杂,需要一些学习才能正确地使用它。我已经将它用于一些东西,如惰性初始化和简单快速的可重用闩锁
尽管它很复杂,但我认为AQS并不特别模糊,它有很好的javadoc描述了如何正确地使用它。

1
java.util.concurrent.AbstractQueuedSynchronizer - Jed Wesley-Smith
实际上:java.util.concurrent.locks.AbstractQueuedSynchronizer - Jed Wesley-Smith

1

0
据我所知,AbstractQueuedSynchronizer被用来管理状态转换。JDK使用它来扩展Sync,一个java.util.concurrent.FutureTask的内部类。Sync类管理FutureTask的状态(READY、RUNNING、RAN和CANCELLED)及其之间的转换。
这使得FutureTask可以像您所知道的那样阻塞在FutureTask.get()上,直到达到RAN状态。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接