Basic Concepts
In this chapter, we will explain the principle of "thread access to Fair lock", and we need to understand a few basic concepts before explaining it. The following are all based on these concepts, which may be tedious, but from these concepts, you can see some of the architecture of the Java lock, which is helpful for us to know about locks.
1. AQS -refers to the Abstractqueuedsynchronizer class.
Aqs is an abstract class that manages "locks" in Java, and many of the public methods of locks are implemented in this class. Aqs is the public parent class for exclusive locks (for example, Reentrantlock) and shared locks (for example, Semaphore).
2. aqs lock category-Divided into " The exclusive lock and shared lock are both.
exclusive lock --locks can only be occupied by a single thread lock at a point in time. It is divided into " fair lock " and " unfair lock ", depending on the acquisition mechanism of the lock. A fair lock is a fair acquisition of a lock in accordance with a first-come-first-served rule through CLH waiting for a thread, and an unfair lock that, when the thread acquires the lock, ignores the CLH waiting queue and acquires the lock directly. The typical real example of an exclusive lock is reentrantlock, in addition, Reentrantreadwritelock.writelock is also an exclusive lock.
() shared lock -a lock that can be shared by multiple threads at the same time. The Reentrantreadwritelock.readlock,cyclicbarrier, countdownlatch and semaphore in the Juc package are shared locks. The uses and principles of these locks are described in more detail in later chapters.
3. CLH Queue --Craig, Landin, and Hagersten lock queue
The CLH queue is the thread queue for "Waiting for locks" in Aqs. In multi-threading, in order to protect competing resources from being manipulated by multiple threads at the same time, we often need to secure these resources through locks. In an exclusive lock, a competing resource can only be accessed by one thread lock at a time, while the other thread waits. CLH is the queue that manages these "wait locks" threads.
The CLH is a non-blocking FIFO queue. That is, when inserting or removing a node inside, it is not blocked in concurrency, but the atomicity of node insertion and removal is ensured through spin locks and CAS.
4. CAs function --Compare and Swap
The CAS function, which is the comparison and Exchange function, is an atomic manipulation function, that is, data that is manipulated by CAS is atomic . For example, functions such as Compareandsethead (), Compareandsettail (), Compareandsetnext (). Their common feature is that the actions performed by these functions are carried out in an atomic manner.
This chapter focuses on how the "fair lock" acquires the lock and the hierarchy unfolds. "Fair lock" involves a lot of knowledge, but in general, not particularly difficult, if the reader can read Aqs and reentrantlock.java the general meaning of the two classes, understanding the principle and mechanism of the lock is not a problem. This chapter is just the author's own a little understanding of the lock, I hope this part of knowledge can help you understand the "fair lock" the acquisition process, understand the "lock" framework.
REENTRANTLOCK Data Structure
UML class diagram of Reentrantlock
Can be seen:
(Reentrantlock) implements the lock interface.
Reentrantlock and sync are the combined relationships. Reentrantlock contains the Sync object, and Sync is a subclass of Aqs, and more importantly, Sync has two subclass Fairsync (Fair lock) and Nonfairsync (non-fair lock). Reentrantlock is an exclusive lock, whether it is a fair lock or an unfair lock, depending on whether the Sync object is "Fairsync instance" or "Nonfairsync instance".
get Fair Lock (based on jdk1.7.0_40)
We know that acquiring a lock is through the lock () function. Below, we expand the process of acquiring a fair lock with lock ().
1. Lock ()
Lock () is implemented in the Fairsync class of Reentrantlock.java, and its source code is as follows:
Final void Lock () { acquire (1);}
description : "Current thread" actually acquires the lock through acquire (1).
This explains the meaning of "1", which is the parameter that sets the "state of the lock". For an exclusive lock, when the lock is in a fetching state, its state value is 0, the lock is first acquired by the thread, and its status value becomes 1.
Since Reentrantlock (fair lock/non-fair lock) is a reentrant lock, an "exclusive lock" can be obtained more by a single thread, and the state +1 of the lock is acquired 1 times. That is, when the lock is first acquired, the state value of the lock is set to 1 by acquire (1), the state value of the lock is set to 2 when the lock is acquired again, and so on ... This is why the incoming parameter is 1 when the lock is acquired.
reentrant means that a lock can be acquired multiple times by a single thread.
2. Acquire ()
Acquire () is implemented in Aqs, and its source code is as follows:
Public Final void Acquire (int arg) { if (!tryacquire (ARG) && Acquirequeued (Addwaiter (node.exclusive), arg)) selfinterrupt ();
(01) "Current thread" first attempts to acquire a lock through Tryacquire (). If it succeeds, it returns directly; if the attempt fails, it goes to the wait queue sort wait (before there may be a need for the thread to wait for the lock).
(02) In the case of a "current thread" attempt to fail, the "current thread" is first added to the end of the CLH queue (non-blocking FIFO queue) by Addwaiter (node.exclusive). The CLH queue is the thread waiting queue.
(03) After executing Addwaiter (node.exclusive), acquirequeued () is called to acquire the lock. Since Reentrantlock is a fair lock at this point, it acquires the lock according to the principle of fairness .
(04) When the "current thread" executes acquirequeued (), it enters into the CLH queue and waits until the lock is acquired to return! If the current thread is interrupted during the hibernation wait, acquirequeued returns True, at which point the current thread calls Selfinterrupt () to create an interrupt for itself. As for why you have to give yourself an interruption, the following is introduced.
I. Tryacquire ()
1. Tryacquire ()
The Fair lock Tryacquire () is implemented in the Fairsync class of Reentrantlock.java, with the following source code:
Reference:
Http://www.cnblogs.com/skywang12345/p/3496147.html
Java Multithreading Series--"Juc lock" 03 of Fair Lock (a)