StringBuilder不安全在哪?StringBuffer又为什么是线程安全的?
StringBuilder 和 StringBuffer都继承了AbstractStringBuilder
@Override public StringBuilder append(String str) { super.append(str); return this; }
可以看出StringBuilder调用了父类也就是AbstractStringBuilder的append方法,进入代码看下
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; }
首先可以看到count+=len; 在多线程下,这个不是原子操作,因此count数值会错乱冲突
str.getChars(0.len,value,count);进入这个方法
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); }
当多线程下进行数据拷贝的时候,char dst[]会出现数组越界异常
那么StringBuffer又什么就是线程安全的呢?
点进去看StringBuffer的源码
@Override public synchronized StringBuffer append(String str) { toStringCache = null; super.append(str); return this; }
super.append(str);调用的依然是父类AbstractStringBuilder的方法,但是注意到StringBuffer使用了synchronized关键字来修饰,可以对append方法进行原子性操作,保证该方法一次只能被一个线程操作

浙公网安备 33010602011771号