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方法进行原子性操作,保证该方法一次只能被一个线程操作

 



posted @ 2020-11-25 15:35  灵笼  阅读(382)  评论(0)    收藏  举报