There are many concurrent articles that mention various locks such as fair locks, optimistic locks, etc. This article introduces the classification of various locks. The introduction is as follows:

  • Fair lock/unfair lock
  • Reentrant lock
  • Exclusive lock/shared lock
  • Mutex/read-write lock
  • Optimistic lock/pessimistic lock
  • Segmented lock
  • Bias lock/lightweight lock/heavyweight lock
  • spinlocks

These categories do not all refer to the state of the lock, some refer to the characteristics of the lock, and some refer to the design of the lock. The following summary of the content is to explain the noun of each lock.

Fair lock/unfair lock

A fair lock is one in which multiple threads acquire locks in the order in which they are applied. An unfair lock means that multiple threads obtain locks in a different order than the one that applied for the locks earlier. Possibly, it could lead to priority reversals or starvation. In the case of Java ReentrantLock, the constructor specifies whether the lock is fair, and the default is unfair. The advantage of an unfair lock is that the throughput is greater than that of a fair lock. Synchronized is also an unfair lock. Because its not like already by AQS (AbstractQueuedSynchronizer) to implement the thread scheduling, so there is no way to make it into a fair lock.

Reentrant lock

A reentrant lock, also known as a recursive lock, means that the inner method automatically acquires the lock when the same thread acquires the lock in the outer method. A bit abstract, here is an example of the code. In the case of Java ReentrantLock, its name can be seen as a ReentrantLock. Its name is ReentrantLock. For Synchronized, it is also a reentrant lock. One benefit of reentrant locks is that deadlocks are somewhat avoided.

synchronized void setA() throws Exception{ Thread.sleep(1000); setB(); } synchronized void setB() throws Exception{ Thread.sleep(1000); }Copy the code

The above code is a feature of a reentrant lock. Without a reentrant lock, setB may not be executed by the current thread, possibly causing a deadlock.

Exclusive lock/shared lock

  • An exclusive lock means that the lock can only be held by one thread at a time.
  • A shared lock means that the lock can be held by multiple threads.

In the case of Java ReentrantLock, this is the exclusive lock. But ReadWriteLock, another implementation of Lock, has a shared read Lock and an exclusive write Lock. The shared lock of read lock ensures that concurrent read is very efficient. Read, write, read, and write processes are mutually exclusive. Exclusive lock and shared lock is also achieved through AQS, through the implementation of different methods, to achieve exclusive or shared. In the case of Synchronized, of course, the lock is exclusive.

Mutex/read-write lock

The exclusive/shared lock mentioned above is a broad term, and the mutex/read-write lock is a concrete implementation.

  • The implementation of mutexes in Java is ReentrantLock
  • The Java implementation of a read/write lock is ReadWriteLock

Optimistic lock/pessimistic lock

Optimistic and pessimistic locks do not refer to specific types of locks, but rather to the perspective of concurrent synchronization.

  • Pessimistic locks believe that concurrent operations on the same data must be modified, even if no modification, it will be considered modified. Therefore, for concurrent operations on the same data, pessimistic locking takes the form of locking. The pessimistic view is that concurrent operations without locking are bound to cause problems.
  • Optimistic locks assume that concurrent operations on the same data will not change. When the data is updated, the data will be updated by trying to update and constantly re – updating. Optimistically, concurrency without locking is fine.

From the above description, we can see that pessimistic lock is suitable for the scenario with a lot of write operations, optimistic lock is suitable for the scenario with a lot of read operations, not locking will bring a lot of performance improvement. Pessimistic locking is used in Java to take advantage of various locks. Optimistic locking is used in Java, is lockless programming, often using CAS algorithm, a typical example is atomic class, through CAS spin atomic operation update.

Segmented lock

Segmented locking is actually a lock design, not a specific lock. For ConcurrentHashMap, its concurrent implementation is to achieve efficient concurrent operations in the form of segmented locking.

ConcurrentHashMap Segment lock, which is similar to the structure of HashMap (JDK7 and JDK8) That is, there is an internal array of entries, each element in the array is a linked list; It is also a ReentrantLock (the Segment inherits ReentrantLock).

When a put element is required, instead of locking the entire HashMap, hashCode first knows which segment it is to be placed in, and then locks that segment. So when multiple threads put elements, as long as they are not placed in a segment, they achieve true parallel inserts.

However, in order to obtain the global information of the HashMap, we need to obtain all the segment locks to obtain the statistics.

Segment locking is designed to refine the granularity of the lock. When an operation does not need to update the entire array, only one item in the array is locked.

Bias lock/lightweight lock/heavyweight lock

These three types of locks refer to lock states and are specific to Synchronized. In Java 5, efficient Synchronized is implemented by introducing a mechanism of lock escalation. The status of these three locks is indicated by an object monitor field in the object header.

  • Biased locking is when a piece of synchronized code is always accessed by a thread, and that thread automatically acquires the lock. Reduce the cost of acquiring locks.
  • Lightweight lock refers to that when a biased lock is accessed by another thread, the biased lock will be upgraded to lightweight lock. Other threads will try to acquire the lock through the form of spin, which will not block and improve performance.
  • Heavyweight lock means that when the lock is a lightweight lock, the other thread spins, but the spin will not continue. When the spin is a certain number of times, the lock has not been acquired, it will enter the block, and the lock expands to the heavyweight lock. Heavyweight locks can block other threads that apply for them and degrade performance.

spinlocks

In Java, a spin lock means that the thread attempting to acquire the lock does not block immediately, but instead attempts to acquire the lock in a loop. This has the advantage of reducing the cost of thread context switching, but the disadvantage is that the loop consumes CPU.

For an example of a typical spinlock implementation, see the spinlock implementation.

Source: cnblogs.com/qifengshi/p/6831055.html

Welcome to follow my wechat public account “Code farming breakthrough”, share Python, Java, big data, machine learning, artificial intelligence and other technologies, pay attention to code farming technology improvement, career breakthrough, thinking transition, 200,000 + code farming growth charge first stop, accompany you have a dream to grow together