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, StringBuilder
and the StringBuffer
source 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 StringBuilder
as well as StringBuffer
the most commonly used is the append
method, 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 AbstractStringBuilder
append 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 StringBuilder
is thread safe.
2, append method of analysis
we look back to AbstractStringBuilder
the append()
fifth line source approach ensureCapacityInternal()
is to check StringBuilder
the original object char
array's capacity can not hold the new string, if you call overflowed the Arrays.copyOf
method for char
array 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.