Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

Example Analysis of AbstractQueuedSynchronizer

2025-04-11 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/03 Report--

This article introduces you to the example analysis of AbstractQueuedSynchronizer, the content is very detailed, interested friends can refer to, hope to be helpful to you.

AbstractQueuedSynchronizer

AQS is an internally maintained FIFO queue + ID (number) model, which is modified using CAS mode as the basic component of the multithreading tool.

Attribute name indicates that volatile Node head as the header node will clean up the associated pre,thread in the Node to avoid GC not recycling the volatile Node tail tail node volatile int state0 for idle other components to use on demand, use cas to assign values, and Thread exclusiveOwnerThread holds threads

State is the int of volatile, which is implemented on demand in different business scenarios.

Exclusive mode:

If state is 0 in ReentrantLock.Sync, it is not locked. > 0 means it is held by several threads.

If state is 0 in ThreadPoolExecutor.Worker, it is not executed.

Sharing mode:

State in CountDownLatch.Sync is specified when initializing, indicating how many threads can hold

State is the same as CountDownLatch in Semaphore.Sync

Mixed mode:

In ReentrantReadWriteLock.Sync, state is a combination of shared lock and exclusive lock, which is divided by 16 bits by bit operation. The maximum number of read and write locks is 65535.

Key method exclusive mode holds resources: acquire

Acquire: exclusive mode acquisition, that is, only one thread can update state. Ignore the interrupt identity and respond to the interrupt after it is obtained.

AcquireInterruptibly: exclusive mode acquisition. If the thread is identified as an interrupt, an exception is thrown.

Public final void acquire (int arg) {if (! tryAcquire (arg) & & acquireQueued (addWaiter (Node.EXCLUSIVE), arg) selfInterrupt ();}

TryAcquire: subclass is implemented on demand. Update state with exclusive mode, add state, return true successfully and return false if failed.

The park will not respond correctly after the interrupt, so you need to reset the thread interrupt identity and compensate for the interrupt after the unpark

Release Resources: release

Release: release resources in exclusive mode

Public final boolean release (int arg) {if (tryRelease (arg)) {Node h = head; if (h! = null & & h.waitStatus! = 0) unparkSuccessor (h); return true;} return false;}

TryRelease: subclasses are implemented on demand, updating state with exclusive mode, reducing state, and handling corresponding exclusive threads

Shared mode holds resources: acquireShared

The acquireShared sharing mode is acquired, ignoring the interrupt thread and interrupting accordingly after the acquisition.

The acquireSharedInterruptibly shared mode is fetched, responding to interrupts, and thread interrupts throw an exception.

Public final void acquireShared (int arg) {if (tryAcquireShared (arg))

< 0) doAcquireShared(arg);} tryAcquireShared:子类按需实现,对返回值有如下要求: 负值:失败。 零:共享模式下的获取成功,但是没有后续共享模式下的获取可以成功。 正值: 如果共享模式下的获取成功并且后续共享模式下的获取也可能成功,则为正值,在这种情况下,后续的等待线程必须检查可用性。 (对三个不同返回值的支持使该方法可以在仅有时进行获取的情况下使用。)成功后,就已经获取了此对象。 释放资源:releaseShared releaseShared:以共享模式释放资源 public final boolean releaseShared(int arg) { if (tryReleaseShared(arg)) { doReleaseShared(); return true; } return false;} tryReleaseShared:子类按需实现,使用共享模式更新state,减少state 其它关键方法检查并更新节点状态:shouldParkAfterFailedAcquire 在park线程之前的判断,当前置节点为取消时更新前置节点 private static boolean shouldParkAfterFailedAcquire(Node pred, Node node) { int ws = pred.waitStatus; if (ws == Node.SIGNAL) /* * This node has already set status asking a release * to signal it, so it can safely park. */ return true; if (ws >

0) {/ * Predecessor was cancelled. Skip over predecessors and * indicate retry. * / do {node.prev = pred = pred.prev;} while (pred.waitStatus > 0); pred.next = node;} else {/ * waitStatus must be 0 or PROPAGATE. Indicate that we * need a signal, but don't park yet. Caller will need to * retry to make sure it cannot acquire before parking. * / compareAndSetWaitStatus (pred, ws, Node.SIGNAL);} return false;} Wake up subsequent nodes: unparkSuccessor

Wake up subsequent nodes and clean up cancelled nodes

Private void unparkSuccessor (Node node) {/ * * If status is negative (i.e., possibly needing signal) try * to clear in anticipation of signalling. It is OK if this * fails or if status is changed by waiting thread. * / int ws = node.waitStatus; if (ws

< 0) compareAndSetWaitStatus(node, ws, 0); /* * Thread to unpark is held in successor, which is normally * just the next node. But if cancelled or apparently null, * traverse backwards from tail to find the actual * non-cancelled successor. */ Node s = node.next; if (s == null || s.waitStatus >

0) {s = null; for (Node t = tail; t! = null & & t! = node; t = t.prev) if (t.waitStatus

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report