This article has participated in the third “topic writing” track of the Denver Creators Training Camp. For details, check out: Digg Project | Creators Training Camp third is ongoing, “write” to make a personal impact.

Preamble: At first I saw this title I felt “familiar, but strange”, because locking is one of the effective means to ensure the atomicity of critical resource operation in the case of concurrency. Below I from our several development use of the point of view we commonly used locks.

What problems can locks solve?

Locking can solve the scenario of sequential access and modification of shared data during the execution of parallel tasks. Such as making parallel deductions or transfers to the same account. Let’s take a look at synchronized, ReetranLock and their use.

synchronized

Synchronized is a built-in lock provided by JDK and implemented internally by JVM. It is based on monitor mechanism and optimized after JDK 1.6. There is a lock upgrade process and the lock state is stored in the object header.

In the process of lock upgrade, the default is no lock state, and the first judgment will be made. If there is no field competition, biased lock will be used. The essence of biased lock is to set the id of the thread that currently obtains the lock to the object header that shares data.

Then upgrade to lightweight locks, the essence of which is to modify MarkWord via CAS.

To upgrade to a heavyweight lock, we can use the operating system monitor to rely on the operating system MutexLock(MutexLock).

Four ways to use it

  1. Used on static methods
  2. Used in ordinary methods
  3. Lock this state
  4. Locking static classes

Lock status record position

Object locks are recorded in the object header as shown in the following figure.

During runtime, the data stored in Mark Word changes as the lock flag bit changes. Mark Word can be changed to store the following four types of data, as shown in the figure below

Lock expansion and upgrade

Locks upgrade and swell irreversibly.

Usage scenarios

Synchroinzed is used in JDK packages.

  1. ConcurrentHashMap (jdk 1.8)
  2. HashTable

ReetrantLock

ReetrantLock was developed by Doug Lea. Since JDK1.5, ReetrantLock was implemented via QAS. The Unsafe package provides CAS operations to compete for lock states. Park (this). If the object in the head of the AQS queue is awakened, execute the unpack method and then let it compete for the lock.

ReetrantLock is also divided into fair and unfair locks. The default is unfair locks. Because fair lock, is to ensure that competitors in the order to obtain the lock, slightly lower performance than unfair lock.

AQS queue structure is shown below, and its essence is a THread-safe synchronization queue of FIFO, as shown in the figure below:

The ReetrantLock process is shown in the following figure:

use

ReetrantLock can be used in three steps: create, lock, and unlock.

 class X {
   private final ReentrantLock lock = new ReentrantLock();
   // ...

   public void m(a) {
     lock.lock();  // block until condition holds
     try {
       // ... method body
     } finally {
       lock.unlock()
     }
   }
 }
Copy the code

Usage scenarios

ReetrantLock: ReetrantLock: ReetrantLock

  1. CyclicBarrier
  2. DelayQueue
  3. LinkedBlockingDeque
  4. ThreadPoolExecutor
  5. ReentrantReadWriteLock
  6. StampedLock

I just listed one step above, which can be said to be a very basic class in ReetrantLock and the basis for our study of concurrency. I will make a more in-depth analysis of the expansion in the subsequent articles.

How do I choose locks?

  1. Synchronized and RentrantLock are used for concurrency control in the JDK for standalone environments.
  2. For autoincrement or atomic data accumulation, you can use the atomic classes provided by Unsafe, for exampleAtomicInteger , AtomicLong
  3. For the database, for the user amount deduction scenario we can use optimistic lock to control, SQL is as follows
update table_name set amount = 100, 
                      version = version + 1 where id = 1 and version = 1;
Copy the code
  1. For distributed scenarios, we need to ensure consistency. We can use Redis or Zk to achieve distributed locks. For concurrency control in distributed scenarios.

The reference information

  • Understanding the Java Virtual Machine in Depth by Zhiming Zhou
  • Blog.csdn.net/wangbo19930…