High-performance programming - Java thread-safety issues related to the lock (Synchronized depth analysis)

The concept of locks in Java

In fact, already mentioned in the previous chapter to explain the atomic and wrote a lock, but this is not enough, Java regarding locks are still many things to learn, here to introduce a few concepts related to the lock.

Spinlocks

It refers to the time when a thread to acquire the lock, if the lock has been acquired by other threads, then the thread will wait for the cycle, and then continue to determine whether the lock is successfully acquired, until the lock is acquired will exit the loop.
Here Insert Picture Description
The figure is a typical scenario, the process of acquiring the lock cycle is the same as in the rotation.

Optimistic locking

Assuming no conflict, if found inconsistent data and previously acquired, then read the latest data when data is modified, the modified retry modified. That reading time and other times not locked, only locked before modification.

Pessimistic locking

Assume concurrency conflicts occur, synchronize all related operations on the data, the data is read from the start locked. That data is read from the beginning to lock up.

Exclusive lock (write lock)

Add resources to write lock, the thread can modify resources, other threads can not be locked; (Write Once)

Shared lock (read lock)

After adding resources to read lock can only be read but not changed, other threads can only add a read lock, write lock can not be added; (read more)

Reentrant lock, the lock is not reentrant

The so-called reentrant value after the thread got a lock, which is free to enter other code by the same lock the synchronization.

Fair locks, lock unfair

Grab the lock is in order to ensure that the order is the order that is fair to grab lock lock to grab the lock.

Synchronized synchronized keyword

  1. Examples of methods, static methods, specified implicitly lock object
  2. As used code block displays the specified lock object
  3. Lock Scope: object lock, lock class, distributed lock
  4. The idea: If more than one process, how do?

Know synchronized

class Counter{

    private static int i=0;

    //synchronized(this){}
    public synchronized void update(){
        //访问数据库
    }

    public void updateBlock(){
        synchronized (this){
            //访问数据库
        }
    }

    //synchronized(Counter.class)
    public static synchronized void staticUpdate(){
        //访问数据库
    }
    
    public static void staticUpdateBlock(){
        synchronized(Counter.class){
            //访问数据库
        }
    }
}

Outlines the use of synchronized from the above pseudo-code, we need to be clear that synchronized is a locking process, but this is not a lock or Counter.class, but after a series of internal JVM handled out.

synchronized features

a reentrant is synchronized, exclusive, pessimistic locking. It also locks elimination, such as lock lock coarsening optimization.

Lock elimination

The idea is to eliminate the lock under certain circumstances, can eliminate the lock means, the process takes place in real-time JIT compile time. Look at a piece of code:

public void test1(Object arg){

        //StringBuilder线程不安全,StringBuffer用了synchronized,是线程安全的
        // jit 优化,消除了锁
        StringBuffer stringBuffer = new StringBuffer(); //局部变量,没有在其他线程中使用
        stringBuffer.append("a");
        stringBuffer.append("b");
        stringBuffer.append("c");

        stringBuffer.append("a");
        stringBuffer.append("b");
        stringBuffer.append("c");

        stringBuffer.append("a");
        stringBuffer.append("b");
        stringBuffer.append("c");
//        System.out.println(stringBuffer.toString());;
    }

Since the beginning of the implementation of the above code when executed will behave, but when the method is performed multiple times will trigger jit compiler, that time will eliminate the synchronized keyword, which is the lock removed. Note, however, this situation exists only in the single-threaded case.

锁粗 of

Used to improve fine-grained locks, put a lot of fine-grained low among the code in a synchronized, to improve performance. For example:
Here Insert Picture Description
The above these small end of the operation to be optimized JVM like the following frame.

synchronized principles of learning

To realize its principles must first go to know how this lock is to lock this object, it's locked state is how to record? The state will be recorded in this object it? If the lock is occupied, then apply the lock thread will be suspended when the lock is released when the thread will awaken suspend the head of the queue queue. To the above mechanism, it is necessary to go in-depth knowledge of learning objects related to:

Java object storage principle

Look at a code, and the Java memory model:
Here Insert Picture Description
Here Insert Picture Description
First int a = 1; basic types of local variables directly stored in the local variable table of the main thread, also the presence of the reference james local variable table.

The class member variable will exist in the heap memory of the object:
Here Insert Picture Description
static variables, methods (static and non-static) are stored in the method area, and objects you want to get to the information they want to rely on the object head to the method point area class. You can get the initial variables and methods. Pay attention to even the references are stored in the object directly point to another object, and the object go through to find the specified class object header:
Here Insert Picture Description

Detailed object header

We need to change the lock to grab a mark, the mark is actually in the object header into, let's look at an object storage head Detailed map:
Here Insert Picture Description

Mark Word

Marks on the lock are stored in the Mark Word (tag field) in. It is essentially a period of heap memory area in memory. Size is 64 bits (32-bit to 32-bit machines).
Here Insert Picture Description
The above five states of Mark Word.
If Mark Word as the first that is not coupled with the lock. The second paragraph is biased locking. The third paragraph is lightweight lock. The fourth paragraph is heavyweight lock.

Lock upgrade process

Here Insert Picture Description

Biased locking

After biased locking in fact, change the 0 to thread ID, in fact, no longer unlock after locking, only useful for a thread scene, there have been no use. JVM parameters may be used -XX: -UseBiasedLocking disable biased locking.

Biased locking, essentially no lock, if any multithreading competition for the lock did not happen, JVM think that is single-threaded, you do not need to synchronize

Lightweight lock

First will lock when Mark Word copied into a stack frame synchronous code block, and then apply all threads CAS operation, thread lock to grab his own Lock record address is written so that other threads can not succeed CAS , no threads are successful spin-demand to a certain extent it will lock escalation.

Heavyweight lock

If the lightweight lock would have been to apply the spin lock, consume CPU performance, so the upgrade for the heavyweight lock, the lock is to apply thread suspension is stored in a entryList, when unlocked again wake up.

Class meta address

Refers to a method in the class area address, used when the object initialization, a pointer corresponds.

Array Length

Length of the array, that is, if the target object is an array, then records its length.

Published 38 original articles · won praise 10 · views 1127

Guess you like

Origin blog.csdn.net/weixin_41746577/article/details/103956823