[Java concurrent programming] lock mechanism (three): synchronized optimization plan & use attention

1. Synchronized optimization plan

1.1 Lock elimination

Lock elimination is to delete unnecessary locking operations. When the virtual machine instant editor is running, it eliminates some locks that "code synchronization is required, but it is detected that there is no shared data competition" .

According to the code escape technique, if it is judged that the data on the heap will not escape the current thread in a piece of code , then it can be considered that this piece of code is thread-safe and does not need to be locked.

Look at the following program:

public class SynchronizedTest {
    
    

    public static void main(String[] args) {
    
    
        SynchronizedTest test = new SynchronizedTest();

        for (int i = 0; i < 100000000; i++) {
    
    
            test.append("abc", "def");
        }
    }

    public void append(String str1, String str2) {
    
    
        StringBuffer sb = new StringBuffer();
        sb.append(str1).append(str2);
    }
}

Although the append of StringBuffer is a synchronous method, the StringBuffer in this program belongs to a local variable and will not escape from this method (that is, the reference of StringBuffer sb is not passed to this method and cannot be obtained by other threads. The reference), so in fact this process is thread-safe and the lock can be eliminated.

1.2 Chain coarsening

If a series of consecutive operations repeatedly lock and unlock the same object , and even the lock operation appears in the loop body, even if there is no thread competition, frequent mutual exclusion synchronization operations will lead to unnecessary performance loss.

If the virtual machine detects that a series of fragmented operations are all locking the same object, it will extend (coarse) the scope of lock synchronization to the outside of the entire operation sequence.

for example:

public class StringBufferTest {
    
    
    StringBuffer stringBuffer = new StringBuffer();

    public void append(){
    
    
        stringBuffer.append("a");
        stringBuffer.append("b");
        stringBuffer.append("c");
    }
}

Every time you call the stringBuffer.append method, you need to lock and unlock. If the virtual machine detects a series of locking and unlocking operations on the same object, it will merge them into a larger range of locking and unlocking Operation, that is, lock during the first append method, and unlock after the last append method ends.

2. Precautions for synchronized use

  • When sync is added to a static method (static), the lock is the class, such as sync (A.class)

  • The lock granularity of sync should be as small as possible to ensure atomicity

  • Synchronized will automatically release the lock when it encounters an exception, which needs to be handled in the catch block

  • Sync can only lock the heap, not String (method area-constant pool)

  • sync is a reentrant lock, call the sync method in the sync block to automatically obtain the lock

  • Simulate deadlock

Guess you like

Origin blog.csdn.net/weixin_43935927/article/details/108656476