当前位置:网站首页>Multi thread tutorial (XXIX) immutable design

Multi thread tutorial (XXIX) immutable design

2022-06-11 05:30:00 Have you become a great God today

Multithreading tutorial ( Twenty-nine ) Immutable design

Common invisibility designs include time formats and string

With string For example , Explain the elements of immutable design

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    
    /** The value is used for character storage. */
    private final char value[];
    /** Cache the hash code for the string */
    private int hash; // Default to 0

    // ...

}

1.final Use

Found this kind of 、 All properties in the class are final Of

  • Properties with final Modification ensures that the property is read-only , Do not modify
  • Class with final Modification ensures that methods in this class cannot be overridden , Prevent subclasses from inadvertently destroying immutability

2. Protective copy

But some students will say , When using strings , There are also some methods related to modification , such as substring etc. , So let's take a look at how these methods are implemented , So substring For example :

public String substring(int beginIndex) {
    
    if (beginIndex < 0) {
    
        throw new StringIndexOutOfBoundsException(beginIndex);
    }
    int subLen = value.length - beginIndex;
    if (subLen < 0) {
    
        throw new StringIndexOutOfBoundsException(subLen);
    }
    return (beginIndex == 0) ? this : new String(value, beginIndex, subLen);
}

It is found that its internal is to call String The constructor of creates a new string , Then enter this structure to see , Whether the final char[] value Made changes :

public String(char value[], int offset, int count) {
    
    if (offset < 0) {
    
        throw new StringIndexOutOfBoundsException(offset);
    }
    if (count <= 0) {
    
        if (count < 0) {
    
            throw new StringIndexOutOfBoundsException(count);
        }
        if (offset <= value.length) {
    
            this.value = "".value;
            return;
        }
    }
    if (offset > value.length - count) {
    
        throw new StringIndexOutOfBoundsException(offset + count);
    }
    this.value = Arrays.copyOfRange(value, offset, offset+count);
}

It turned out that there was no , When constructing a new string object , Will create a new char[] value, Copy content . This means of avoiding sharing by creating replica objects is called 【 Protective copy (defensive copy)】

3. final principle

public class TestFinal {
    
 final int a = 20; }

Bytecode

0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: aload_0
5: bipush 20
7: putfield #2 // Field a:I
 <--  Write barriers 
10: return

Find out final The assignment of variables will also pass putfield Order to complete , Similarly, a write barrier will be added after this instruction , Ensure that when other threads read its value, it will not appear as 0 The situation of

More detailed final Principle explanation : (https://forlogen.blog.csdn.net/article/details/105655338)

actually final It can be used as common assignment putfield Bytecode instruction , Add a write barrier after the bytecode to ensure thread safety

The write barrier prevents reordering of instructions

In any constructor for a final The changes to the domain , And then assign the reference of this construction object to another reference variable , These two operations cannot be reordered

Between the lines : Before the object reference is visible to any thread , Object's final The domain has been properly initialized .

Read an include for the first time final References to domain objects , And then read this for the first time final Domain , There is no reordering between the two operations

Between the lines : Only if you get the inclusion final References to domain objects , Can be read later final Domain value .

原网站

版权声明
本文为[Have you become a great God today]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/03/202203020539055584.html