Java Collections Series Five: StringBuilder Why not thread-safe?

introduction

In fact StringBuilder does not belong to the set, but in order not to open new article series, this series of articles written on the inside. We are in the process of the interview, the interviewer will sometimes point steady Java-based issues such as HashMap related issues and so on. We all know that StringBuilder is not thread-safe, so if the interview process, the interviewer continue to ask why it is not thread-safe, many people are stuck on this issue.

  • Source code analysis
  • to sum up

First, source code analysis

1, append analysis method
shown below, StringBuilderand the StringBuffersource code is as follows, they have inherited AbstractStringBuilder:

public final class StringBuilder
    extends AbstractStringBuilder
    implements java.io.Serializable, CharSequence
{
...
}
 public final class StringBuffer
    extends AbstractStringBuilder
    implements java.io.Serializable, CharSequence
{
...
}

Parent class member variables used are as follows:

//存储字符串的数据
char[] value;
//已经使用的字符数组数量
int count;

I use it StringBuilderas well as StringBufferthe most commonly used is the appendmethod, as follows:

//可以追加任意对象
@Override
public StringBuilder append(Object obj) {
        return append(String.valueOf(obj));
    }
//可以追加字符串
@Override
public StringBuilder append(String str) {
        super.append(str);
        return this;
    }

Actually it calls the parent class AbstractStringBuilderappend method. as follows:

 public AbstractStringBuilder append(String str) {
        if (str == null)
            return appendNull();
        int len = str.length();
        ensureCapacityInternal(count + len);
        str.getChars(0, len, value, count);
        //变量数据更新
        count += len;
        return this;
    }

As can be seen from the above code count += len;is not an atomic operation. At this count value is 10 for example, len is 1, two threads to simultaneously execute the seventh row, to get the count values are 10, after executing the assignment result of the addition to the count, so the implementation of the latter two threads A count value of 11, instead of 12. So StringBuilderis thread safe.

2, append method of analysis
we look back to AbstractStringBuilderthe append()fifth line source approach ensureCapacityInternal()is to check StringBuilderthe original object chararray's capacity can not hold the new string, if you call overflowed the Arrays.copyOfmethod for chararray expansion.

 private void ensureCapacityInternal(int minimumCapacity) {
        // overflow-conscious code
        if (minimumCapacity - value.length > 0) {
            value = Arrays.copyOf(value,
                    newCapacity(minimumCapacity));
        }
    }
 public static char[] copyOf(char[] original, int newLength) {
        char[] copy = new char[newLength];
        System.arraycopy(original, 0, copy, 0,
                         Math.min(original.length, newLength));
        return copy;
    }
public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin) {
        if (srcBegin < 0) {
            throw new StringIndexOutOfBoundsException(srcBegin);
        }
        if (srcEnd > value.length) {
            throw new StringIndexOutOfBoundsException(srcEnd);
        }
        if (srcBegin > srcEnd) {
            throw new StringIndexOutOfBoundsException(srcEnd - srcBegin);
        }
        System.arraycopy(value, srcBegin, dst, dstBegin, srcEnd - srcBegin);
    }

Second, summary

Some threads unsafe operation exists JDK source code, in fact, because there is no corresponding synchronous operation to ensure that atomic operations. So we can be analyzed by this, and can be properly optimized and improved.

Published 88 original articles · won praise 49 · Views 100,000 +

Guess you like

Origin blog.csdn.net/Diamond_Tao/article/details/102129598