Synchronized resolve - if you're willing to peel layer by layer, my heart

Foreword

synchronized, a sharp knife to solve the problem of access to data synchronization of concurrency. So what is the underlying principle of synchronized is it? Let's peel one layer at its heart, is like peeling an onion, to see what happens.

Synchronized usage scenarios

synchronized keyword can be applied to methods or code blocks, there are several main use, as shown:

Next, we synchronized to peel the first layer, the decompiled code block and a method for its role .

acting synchronized code block

public class SynchronizedTest {

    public void doSth(){
        synchronized (SynchronizedTest.class){
            System.out.println("test Synchronized" );
        }
    }
}
复制代码

Decompile, available:

FIG available, add a keyword synchronized code block, more than two instructions the monitorenter, the monitorexit . That JVM uses two instructions monitorenter and monitorexit synchronization, monitorenter, monitorexit and how to ensure the synchronization of it? We continue to explore the next, etc. The second layer peeling.

synchronized method acting

 public synchronized void doSth(){
            System.out.println("test Synchronized method" );
    }
复制代码

Decompile, available:

It can be obtained from the FIG., A method of adding the synchronized keyword, more ACC_SYNCHRONIZED marker. I.e., JVM access identifier by the method (the flags) was added ACC_SYNCHRONIZED to achieve synchronization.

monitorenter、monitorexit、ACC_SYNCHRONIZED

Peeling the first layer, decompile synchronized methods and blocks of code, we already know synchronized to achieve synchronization, they are three action by Shane monitorenter, monitorexit, ACC_SYNCHRONIZED? We then peel the second layer:

monitorenter

monitorenter instructions Introduction

Each object is associated with a monitor. A monitor is locked if and only if it has an owner. The thread that executes monitorenter attempts to gain ownership of the monitor associated with objectref, as follows:

If the entry count of the monitor associated with objectref is zero, the thread enters the monitor and sets its entry count to one. The thread is then the owner of the monitor.

If the thread already owns the monitor associated with objectref, it reenters the monitor, incrementing its entry count.

If another thread already owns the monitor associated with objectref, the thread blocks until the monitor's entry count is zero, then tries again to gain ownership.

Google translate, as follows:

Each object with a monitor is associated. If and only if you have the owner (owned), monitor will be locked. Monitorenter instruction to execute threads will try to obtain the corresponding monitor, as follows:

When each object maintains a record of the number of times counter is locked, the object is not locked, the counter is zero. A thread enters a monitor (monitorenter instruction execution), the counter will be set to 1.

When the lock of the object of obtaining the same thread again, the counter increment again.

When other threads want to get the monitor, it will block until the counter is zero to succeed.

You can look at the following figures, used to facilitate the understanding:

monitorexit

monitorexit instructions Introduction

The thread that executes monitorexit must be the owner of the monitor associated with the instance referenced by objectref.

The thread decrements the entry count of the monitor associated with objectref. If as a result the value of the entry count is zero, the thread exits the monitor and is no longer its owner. Other threads that are blocking to enter the monitor are allowed to attempt to do so.

Google translate, as follows:

monitor the owner of the thread to perform monitorexit instruction.

Monitorexit thread executes the instruction, it will allow monitor counter by one. If the counter is 0, indicating that the thread no longer has a monitor. Other threads allows the monitor to try to get the.

You can look at the following figures, used to facilitate the understanding:

ACC_SYNCHRONIZED

ACC_SYNCHRONIZED Introduction

Method-level synchronization is performed implicitly, as part of method invocation and return. A synchronized method is distinguished in the run-time constant pool’s method_info structure by the ACC_SYNCHRONIZED flag, which is checked by the method invocation instructions. When invoking a method for which ACC_SYNCHRONIZED is set, the executing thread enters a monitor, invokes the method itself, and exits the monitor whether the method invocation completes normally or abruptly. During the time the executing thread owns the monitor, no other thread may enter it. If an exception is thrown during invocation of the synchronized method and the synchronized method does not handle the exception, the monitor for the method is automatically exited before the exception is rethrown out of the synchronized method.

Google translate, as follows:

Method-level synchronization is implicit, as part of the method call. There will be a constant pool ACC_SYNCHRONIZED mark synchronization method.

When you call a method ACC_SYNCHRONIZED flag is set, execution threads need to get monitor locks and then begins execution method, and then release the monitor lock after execution method, whether it is normal when the method throws an exception or return will release corresponding monitor lock.

During this period, if other threads to execute the request method, because the monitor can not get a lock to be blocked to live.

If during the execution of the method, the occurrence of abnormality, and the internal method does not handle the exception, the monitor lock is automatically released before the exception is thrown out method.

You can look at the flow chart:

The second layer summary Synchronized

  • Synchronization code block is realized by the monitorexit monitorenter and, when the first thread of execution to monitorenter monitor lock is obtained to perform the latter method. When a thread of execution to monitorexit will have to release the lock.
  • Synchronization method is achieved by setting ACC_SYNCHRONIZED flag, when the thread execution method has ACC_SYNCHRONI logo, need to get monitor lock.
  • Each object maintains a lock counter, 0 means may be other threads get locked, not 0, only the current thread lock to get the lock again.
  • Synchronization method and a synchronization block bottom are achieved by a synchronization monitor.
  • Each object is associated with a monitor, a thread can occupy or release monitor.

Well, peel here, there are some places we do not know, what monitor is it, and why it can synchronize it? And how objects associated with monitor it? Objective Do not worry, we continue to peel a layer, please read on.

monitor monitor

montor in the end what is it? We then peel the third layer Synchronized what monitor that? It will be appreciated that as a synchronization tool , or a synchronization mechanism , which is generally described as an object. OS tube- concept principle, ObjectMonitor is its realization of the principle.

The operating system the tube

  • The tube (English: Monitors, also referred to as a monitor) is a program structure, a plurality of subprograms multiple worker threads (modules or objects) within the structure formed by mutually exclusive access to shared resources.
  • These shared resources are generally a hardware device or a group of variables. The tube realized at one point in time, at most only one thread executing a subroutine of the tube.
  • Compared with those of a concurrent program implemented mutually exclusive access to data by modifying the structure design, the tube to achieve greatly simplifies programming.
  • The tube provides a mechanism, a thread can temporarily give up exclusive access, wait for certain conditions are met, to regain the implementation of the right to recover its exclusive access.

ObjectMonitor

ObjectMonitor data structure

In the Java virtual machine (the HotSpot) in, Monitor (tube side) ObjectMonitor is implemented, the main data structure is as follows:

 ObjectMonitor() {
    _header       = NULL;
    _count        = 0; // 记录个数
    _waiters      = 0,
    _recursions   = 0;
    _object       = NULL;
    _owner        = NULL;
    _WaitSet      = NULL;  // 处于wait状态的线程,会被加入到_WaitSet
    _WaitSetLock  = 0 ;
    _Responsible  = NULL ;
    _succ         = NULL ;
    _cxq          = NULL ;
    FreeNext      = NULL ;
    _EntryList    = NULL ;  // 处于等待锁block状态的线程,会被加入到该列表
    _SpinFreq     = 0 ;
    _SpinClock    = 0 ;
    OwnerIsThread = 0 ;
  }
复制代码

ObjectMonitor keyword

Several key meanings as shown in FIG segment ObjectMonitor:

Working Mechanism

Working mechanism of Java Monitor as shown:

  • I want to get monitor thread will first enter _EntryList queue.
  • When a thread to acquire the object monitor, enter _Owner area, set to the current thread, while _count counter is incremented.
  • If a thread calls the wait () method, it will enter _WaitSet queue. It will release the monitor lock, will soon _owner assigned to null, _count from minus 1, enter _WaitSet blocked waiting queue.
  • If another thread calls notify () / notifyAll (), wakes up in a thread _WaitSet, the thread attempts to acquire a monitor lock again, successfully enter into _Owner area.
  • Synchronization method is finished, the thread exits the critical region, will monitor the owner set to null, and release the monitor lock.

For vivid point, for example:

  synchronized(this){  //进入_EntryList队列
            doSth();
            this.wait();  //进入_WaitSet队列
        }
复制代码

OK, we peel layer, know what monitor is, that it is how the object is associated with monitor it? You dudes and babes who, we read on, to take off a layer.

Monitor associated with the object

How to monitor objects are associated with it? Direct look at the map:

After reading the chart, in fact, how the object is associated with the monitor, we already have a general understanding, then we divide the object memory layout, object header, MarkWord layers continue to explore down.

Memory layout objects

In HotSpot VM, the object is stored in memory layout may be divided into three areas: object header (Header), instance data (Instance Data) and filled objects (Padding).

  • Examples of data : real significance information object is stored, the attribute data store class, attribute information including the parent class;
  • Alignment padding : Since the virtual machine start-request object address must be an integer multiple of 8 bytes. Padding data need not be present, only for byte alignment.
  • Object header : Hotspot virtual machine object header includes two pieces of data: Mark Word (marker fields), Class Pointer (pointer type).

Object header

The main object header data consists of two parts: Mark Word (marker fields), Class Pointer (pointer type).

  • The Pointer class : class directed to it is the object metadata pointer, the virtual machine is determined by a pointer to which this object is an instance of the class
  • Word Mark : is used to store runtime data object itself, it is the realization of lightweight lock and key lock bias.

Mark word

Mark Word for storing runtime data object itself, such as a hash code (HashCode), GC generational age lock state flag thread holds the lock, the thread ID bias, bias timestamp.

In the 32-bit HotSpot virtual machine, if the object is in the unlocked state, then the 32bit space Mark Word's target of 25 for storing the hash code, 4bit used to store objects generational ages, 2bit for storage lock flag, 1bit fixed at 0, represents a non-biased locking. Other states as shown below:

  • The previous analysis shows, monitor features are mutually exclusive performed, then meow you look on the map, heavyweight lock, point mutex pointer .
  • In fact, it is synchronized heavyweight lock , that is to say Synchronized object lock, Mark Word lock flag is 10, which is a pointer to the starting address Monitor object.
  • Suddenly, the vista is not feeling it! How to monitor the associated object? The answer: Mark Word heavyweight lock, a pointer to the monitor address .

Synchronized peel fourth-story summary

How objects associated with the monitor?

  • There are objects object header
  • Object header inside Mark Word
  • Mark Word pointer to the monitor

Lock optimization

In fact, only before JDK1.6, synchronized implementation will directly call ObjectMonitor the enter and exit, this lock is called heavyweight lock. A heavyweight lock, why we often use it? JDK6 from the beginning, HotSpot Java virtual machine development team to optimize the lock, such as increasing the adaptability of spin locks elimination, lock coarsening, lightweight locks and lock biased optimization strategy.

Spinlocks

What is the spin lock?

Spin lock means that when a thread tries to acquire a lock if the lock is held by other threads, has been circulating detect whether the lock is released, rather than into the thread suspend or sleep state.

Why do you need a spin lock?

Blocking and wake up the thread needs CPU goes into kernel mode from user mode, blocking and frequently wake up the CPU as apparently do not say anything bitter words. In fact, many times, locked state only lasts for a short period of time, for a short period of time, blocking and frequently went to wake up the thread definitely not worth it. So spin locks came into being.

Spin lock scenario

Suitable for small spin lock lock to protect critical section, the critical section is small, then the lock takes very short time.

Spin lock some thoughts

Here, I want to talk about, Why give up ConcurrentHashMap segment locks, use CAS spin mode , it is actually the truth.

Lock elimination

What is a lock to eliminate?

Lock is a virtual machine slashing time compiler at run time, for some of the code requires synchronization, but can not be detected shared data latched competition will be deleted.

Lock eliminate some of the thinking

Here, I would like to be extended to the daily code development, some developers, in the absence of concurrent circumstances, use lock. If no concurrency may directly up on ConcurrentHashMap.

Lock coarsening

What is the lock of the rent?

Lock profanity concept is better understood, that a plurality of consecutive locking, unlocking operation are connected together, a greater range of extension into the lock.

Why do I need to rent a lock of?

In synchronous lock when the need to allow scope sync blocks as small as possible - only synchronize only the actual scope of shared data, the aim is to make the number of operations that need to be synchronized as small as possible, if there is a lock competition, the thread waiting for the lock can get the lock as soon as possible. But if the lock unlock a series of continuous operation, it may result in unnecessary performance loss, so the introduction of the concept of lock foul language.

Thinking lock metaphor of rent

For example, tickets zoo. Teacher took a group of children to visit, train you if you know they are a group, you can see them as a whole (lock of rent), a one-time ticket too, without having to find them one by one ticket.

to sum up

Synchronized onion us directly to a map as a summary of it, if you are willing to peel layer by layer, my heart.

Reference and thanks

Personal Public Number

Welcome to the concern, we will study together, discuss Kazakhstan.

Guess you like

Origin juejin.im/post/5d5374076fb9a06ac76da894