[JUC source code] Several questions about AQS

1. Tell me about your understanding of AQS?

Answer: The answer is from big to small, from full to detailed, from use to principle.

  1. AQS is a lock framework . It defines the implementation mechanism of locks and opens up extensions for subclasses to implement. For example, when we are in lock, AQS opens the state field so that subclasses can decide whether or not according to the state field. Able to obtain locks, AQS will automatically manage threads that cannot obtain locks, without subclass locks. This is the internal mechanism of lock time locks, which is well encapsulated and exposes the areas where subclass locks need to be extended;
  2. The bottom layer of AQS is composed of a synchronous queue + a conditional queue . The synchronous queue manages the queuing and release of threads that cannot acquire a lock. The conditional queue is a supplement to the synchronous queue in certain scenarios, such as the thread that acquires the lock from the empty queue. If you get the data, you will definitely not get the data. At this time, the conditional queue will manage the thread and block the thread;
  3. AQS provides four scenarios around two queues, namely: acquiring locks, releasing locks, blocking of conditional queues, and waking up of conditional queues . For specific content, please refer to the previous AQS source code analysis .

2. Multiple threads share resources through lock requests, what should I do if the thread cannot obtain the lock?

Answer: Locking (exclusive lock) is mainly divided into the following four steps:

  1. Try to obtain the lock, return directly if the lock is obtained, and go to 2 if the lock is not obtained;
  2. Use Node to encapsulate the current thread and append to the end of the synchronization queue. When appending to the end of the queue, there are two more steps, such as 3 and 4;
  3. Spin + CAS ensures that the state of the previous node is set to signal;
  4. Block yourself, so that the current thread enters the waiting state.

The thread that cannot acquire the lock will perform steps 2, 3, and 4, and will eventually fall into a waiting state. This describes an exclusive lock.

3. In the previous question, is the processing mechanism of exclusive lock and shared lock the same?

Answer: The steps 2, 3, and 4 in question 2 are the same for exclusive locks and shared locks. The difference lies in the first step. When a thread obtains an exclusive lock, it only sets itself as the head node of the synchronization queue. Yes, but if it is a shared lock, it will wake up its subsequent nodes to obtain the lock together

4. The difference between shared lock and exclusive lock?

answer:

  • Exclusive lock means that at the same time, only one thread can acquire the lock, and only one thread can release the lock.
  • Shared locks can allow multiple threads to acquire the same lock, and you can set the number of threads to acquire the lock. The reason why shared locks can do this is because once a thread acquires a shared lock, it will set itself as the head node of the synchronization queue. After the head node is released automatically, the nodes waiting to acquire the shared lock, so that these waiting nodes also obtain the shared lock together, while the exclusive lock will not do this.

5. Exclusive lock and shared lock refer to the strategy when locking, so is there a strategy for exclusive lock and shared lock when the lock is released?

Answer: Yes, exclusive locks and shared locks are mainly reflected in whether multiple threads can obtain the same lock when locking. But when the lock is released, there is no concept and strategy of exclusive lock and shared lock, the concept is only for lock acquisition.

6. Describe the synchronization queue?

answer:

  • The underlying data structure of the synchronization queue is a doubly linked list . The node is called Node, the head node is called head, and the tail node is called tail. The front and back directions between nodes and nodes are called prev and next respectively. If it is a face-to-face interview, you can draw the overall AQS architecture diagram. Sync queue in.

  • The role of the synchronization queue: to block threads that cannot obtain a lock, and release these threads at an appropriate time.

  • The general process of implementation: when multiple threads are requesting a lock, at a certain time only one thread can obtain the lock (exclusive lock), then the remaining threads that cannot obtain the lock will queue and block in the synchronization queue By myself, when a thread actively releases the lock, it will release a queued thread from the head node in the synchronization queue and let the thread compete for the lock again.

7. When and how does the thread enter and leave the synchronization queue?

Answer: (Exclusive lock as an example) There are two opportunities for entering and leaving the team.

  • When to join the synchronization queue:
    1. Multiple threads request a lock, and threads that cannot acquire the lock need to be queued and blocked in the synchronization queue;
    2. The nodes in the conditional queue are awakened and transferred from the conditional queue to the synchronous queue.
  • When to dequeue the synchronization queue:
    1. When the lock is released, the head node goes out of the team;
    2. When the thread that obtains the lock enters the condition queue, the lock is released, and the head node of the synchronization queue starts to compete for the lock.

The four timing process can refer to the AQS source code analysis , 1 refer to the acquire method execution process, 2 refer to the signal method, 3 refer to the release method, 4 refer to the await method.

8. Why does AQS need conditional queues after having synchronized queues?

Answer: Under normal circumstances, we only need to have a synchronous queue, but after the lock is locked and the operation queue is required, a synchronous queue is not available, and a conditional queue is needed to supplement the function. For example, when the queue is full, The thread performing the put operation will enter the conditional queue to wait. When the queue is empty, the thread performing the take operation will also enter the conditional queue to wait. To a certain extent, the conditional queue is a supplement to the scene function of the synchronous queue.

9. When and how are elements in the conditional queue entering and leaving the queue?

answer:

  • Time to queue: When the await method is executed, the current thread will release the lock and enter the condition queue.

  • Dequeue timing: When the signal and signalAll methods are executed, the node will transfer from the condition queue to the synchronization queue.

For the specific execution process, please refer to the await and signal methods in the AQS source code analysis .

10. When and how does the node in the conditional queue transfer to the synchronous queue?

Answer: Timing: When a thread executes the signal and signalAll methods, start from the head node of the condition queue and transfer to the synchronization queue. The process is mainly the following steps:

  1. The head node of the condition queue is found, the next attribute of the head node is set to null, and it is removed from the condition queue;
  2. The head node is appended to the end of the synchronization queue;
  3. The head node status (waitStatus) is changed from CONDITION to 0 (initialization status);
  4. Set the state of the previous node of the node to SIGNAL.

11. When a thread enters the conditional queue, why does it need to release the held lock?

Answer: The reason is very simple. If the current thread does not release the lock, once it goes to the conditional queue and becomes blocked, all subsequent threads cannot obtain the lock. The correct scenario should be: the current thread releases the lock and blocks in the conditional queue. , Other threads can still obtain the current lock.

Guess you like

Origin blog.csdn.net/weixin_43935927/article/details/108699927