A synchronized is introduced

Synchronized is a built-in LOCK of JVM, which is realized through the internal object Monitor. Synchronization of methods and code blocks is realized based on entering and exiting the Monitor object. The realization of the Monitor lock ultimately depends on the operating system Mutex lock.

2. Synchronized usage

Synchronized can be used in three main ways.

1. Synchronize class methods

public synchronized void method()
{
   // todo
}

Copy the code

Locks the current class object;

2. Synchronize code blocks

public class TestNotes { private static Object object; Public String decStock() {synchronized (object) {//todo} return "synchronized "; }}Copy the code

or

public  void run() {
   synchronized(this) {
      //todo
   }
}

Copy the code

It locks the objects inside the parentheses;

3. Decorate a class

lass ClassName {
   public void method() {
      synchronized(ClassName.class) {
         // todo
      }
   }
}

Copy the code

Java object composition

A Java object consists of three parts:

  • Object header: a complex, synchronized lock that holds some bits of data in it. The object header size is fixed;
  • Instance data: is the business data of the object;
  • Align the fill bits: 64-bit JVMS require the object size to be an integer multiple of 8 bytes by default, so sometimes you need to align the fill bits.

Mark Word

Where, the different states of the lock exist in the Mark Word area of the object header,

The following figure shows the specific area distribution of the 32-bit system Mark Word:

4. Lock upgrade process

Synchronized locks have the following four states:

  • No lock, resources are not locked, only one thread can modify resources successfully, the other threads will retry.
  • Biased lock: When the same thread obtains synchronous resources without competition from others, all synchronization operations are removed, which is equivalent to no lock.
  • Lightweight lock. When multiple threads scramble for synchronous resources, the thread that does not acquire the lock uses CAS spin to wait for the release of the lock.
  • Heavyweight lock: When multiple threads scramble for synchronization resources, the mutex of the operating system is used for synchronization, and the thread that does not obtain the lock is blocked and waits to wake up.

Upgrade process of lock: no lock – “partial lock -” “Lightweight lock -” “heavyweight lock. Note that the upgrade does not have to be hierarchical. It may be possible to upgrade across levels, such as from a no-lock state to a lightweight lock.

Let’s take this code as an example to analyze the specific upgrade process of the following locks:

public class TestNotes { private static Object object; Public String decStock() {synchronized (object) {//todo} return "synchronized "; }}Copy the code

In this code, synchronized locks object instance objects, and the specific state of the lock is stored in the Markword area of the head of object objects.

1. No lock state:

Step description: 1. In the markword area of the object header of a synchronized lock, the initial lock status flag bit is 001 by default, that is, no lock status.

2. Biased lock state:

At some point, thread 1 executes the synchronization code block, and the virtual machine uses CAS to try to change the status flag bit to bias lock state, and records the thread ID of thread 1 into the 23bit bit in the MarkWord area to enter the bias lock state, as shown below:

After entering the biased lock state, if there is no competition from other threads, when thread 1 accesses the synchronized code block again, the JVM will directly run the synchronized code block without CAS locking or unlocking. Until thread 1 completes execution, the JVM releases the bias lock, restoring the markword identifier bit to its initial state.

3. Lightweight lock state:

While thread 1 is holding the bias lock, thread 2 is coming, and the part on the right side of the picture shows thread 2 executing:

Thread 2 accesses the synchronized code block and attempts to acquire the lock; The JVM checks the status of thread 1, and since thread 1 still holds the lock, the JVM cannot revoke the lock on thread 1. Instead, the JVM upgrades the lock to a lightweight lock. This is a 23bit area that holds thread 1’s address and points to a block in thread 1’s stack. At the same time, this piece of memory in the thread stack also holds a reference to MarkWord, which is equivalent to the two areas exchanging content.

The process described above changes from no locking, then to biased locking, then to lightweight locking; However, in some scenarios, the lock can be upgraded directly from no lock to lightweight lock, as shown in the following procedure:

In the figure above, at a certain point, two threads are executing a synchronized block, but only one thread must enter first. If it is thread 1, it will go directly into the lightweight lock state.

At this point, thread 2 performs CAS spin, looking for an opportunity to acquire a lightweight lock, as shown below:

4. Heavyweight lock status:

In the figure above, after entering the lightweight lock state, thread 2 continues spinning to try to acquire the lock. Synchronized does not immediately enter the heavyweight lock state, but instead waits until thread 2 has reached a certain number of spins before the JVM bulges into the heavyweight lock shown below. This number of spins, JDK7 and later can be set by JVM parameters.

Thread 1 performed synchronized code block, the JVM attempts to release the lock, modify markword as the initial state of unlocked, the lock is released, found that is already locked the weight, that there are other threads competition, and other threads must have entered the blocking state, then the JVM after the lock is released, will wake up the other into the blocking state of threads.

In live.

Synchronized has been optimized in JDK 1.6 version, and its performance has been greatly improved. Basically, there is no difference between Synchronized and Java lock performance. Therefore, in the production environment, synchronized can be used as simple and convenient as possible.

The key of optimization is the addition of lightweight lock, the use of CAS, as well as adaptive mechanism, avoiding the application of mutex to the underlying operating system, avoiding the switch between user mode and kernel mode, that is, to a certain extent, avoiding the switch of thread context, temporarily do not enter the state of heavyweight lock.

Series of interview questions

In addition has been doing Java interview serialized series of columns, this time we can finally whoring for nothing

2021 senior most full Java interview questions, liver!

Ali 2021 the most complete new Java interview questions summary

Bytedance Toutiao Front end via (4 rounds of technical surface + HR surface)

Understand Java IO: byte streams, character streams, buffered streams – the most detailed summary!

1. What are the differences between JDK, JRE and JVM?

Java advanced, you must master these data structures

Java concurrent interview, fortunately a little way, otherwise fooled again

Java Object-oriented Design? One way to learn OOPS programming

Java Dynamic Proxy — the skills that make you stand out in your interview

Do you Really understand the Java Virtual Machine?

Thoroughly understand value passing and reference passing in Java

Java hundreds of millions of levels of seckill system optimization, to achieve real high performance high concurrency!

In-depth understanding of JAVA thread interrupt method experience summary

In-depth knowledge of Java like loading and case studies

Learn more about Java garbage collection

Scenario application analysis of the six principles of Java design pattern

How do YOU gracefully null in Java

Who do you give the offer to?

Author: Rain Sword yyy Link: blog.csdn.net/csdn_201508… Source: CSDN

The synchronized keyword is an integral part of concurrent programming. Every object in Java can be used as a lock, which is the basis of synchronized implementation:

Common synchronization method (instance method), lock is the current instance object, before entering the synchronization code to obtain the current instance of the lock static synchronization method, lock is the current class object, before entering the synchronization code to obtain the current class object of the lock synchronization method block, lock is the object in parentheses, the given object lock, The lock for the given object is acquired before entering the synchronous code base.

Synchronized is one of the most common and simplest ways to solve concurrency problems in Java by ensuring mutually exclusive access to Synchronized code

Personally, I think it will be of great help to understand its internal operation principle. I hope this article can help you!

This article is published by OpenWrite!