introdução
Na verdade StringBuilder não pertence ao conjunto, mas de forma a não nova série de artigos em aberto, esta série de artigos escritos no interior. Estamos no processo da entrevista, o entrevistador vai às vezes apontam problemas constantes com base em Java, tais como questões relacionadas com HashMap e assim por diante. Nós todos sabemos que StringBuilder não é thread-safe, por isso, se o processo de entrevista, o entrevistador continuar a perguntar por que não é thread-safe, muitas pessoas estão presas sobre esta questão.
- análise de código fonte
- resumo
Primeiro, análise de código fonte
1, o método de análise de acréscimo
mostrado abaixo, StringBuilder
e o StringBuffer
código fonte é como se segue, que herdaram AbstractStringBuilder
:
public final class StringBuilder
extends AbstractStringBuilder
implements java.io.Serializable, CharSequence
{
...
}
public final class StringBuffer
extends AbstractStringBuilder
implements java.io.Serializable, CharSequence
{
...
}
variáveis de membros da classe pai utilizados são os seguintes:
//存储字符串的数据
char[] value;
//已经使用的字符数组数量
int count;
Eu o uso StringBuilder
, bem como StringBuffer
o mais vulgarmente utilizado é o append
método, como se segue:
//可以追加任意对象
@Override
public StringBuilder append(Object obj) {
return append(String.valueOf(obj));
}
//可以追加字符串
@Override
public StringBuilder append(String str) {
super.append(str);
return this;
}
Na verdade, ele chama o pai classe AbstractStringBuilder
método de acréscimo. Da seguinte forma:
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;
}
Como pode ser visto a partir do código acima count += len;
não é uma operação atômica. Neste valor de contagem é de 10, por exemplo, len é 1, dois threads simultaneamente executar a sétima linha, para obter os valores de contagem são 10, após a execução do resultado atribuição de adição para a contagem, assim que a implementação dos dois últimos tópicos Um valor de contagem de 11, em vez de 12. Então StringBuilder
é thread-safe.
2, método de acréscimo de análise
olhamos de volta para AbstractStringBuilder
o append()
quinto abordagem linha fonte ensureCapacityInternal()
é verificar StringBuilder
o objeto original char
a capacidade da matriz não pode conter a nova cadeia, se você chamar transbordou o Arrays.copyOf
método para char
expansão da matriz.
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);
}
Em segundo lugar, o resumo
Alguns tópicos operação insegura existe código fonte JDK, na verdade, porque não há nenhuma operação síncrona correspondente a assegurar que as operações atômicas. Por isso, podem ser analisados por este, e pode ser devidamente otimizado e melhorado.