StringBuilder解析
最佳答案 问答题库808位专家为你答疑解惑
StringBuilder和StringBuffer相似,两个类的构造器和方法也基本相同。不同的是StringBuffer是线程安全的,StringBuilder没有实现线程安全功能,所以性能略高。StringBuffer类中的方法都添加了synchronized关键字,给方法添加了一个锁,用来保证线程安全。Java9改进了字符串(包括String、StringBuffer、StringBuilder)的实现。在Java9以前字符串采用char[]数组来保存字符,字符串的每个字符占2字节,Java9的字符串采用byte[]数组再加一个encoding-flag字段来保存字符,字符串的每个字符只占1字节,所以Java9的字符串更加节省空间。
StringBuilder源码
@Override@HotSpotIntrinsicCandidatepublic StringBuilder append(String str) {super.append(str);return this;}
是什么导致了StringBuilder的线程不安全,进入父类AbstractStringBuilder
public AbstractStringBuilder append(String str) {if (str == null) {return appendNull();}int len = str.length();ensureCapacityInternal(count + len);putStringAt(count, str);count += len;return this;}
问题在这两行
ensureCapacityInternal(count + len);
putStringAt(count, str);
ensureCapacityInternal() 是一个扩容方法
private void ensureCapacityInternal(int minimumCapacity) {// overflow-conscious codeint oldCapacity = value.length >> coder;if (minimumCapacity - oldCapacity > 0) {value = Arrays.copyOf(value,newCapacity(minimumCapacity) << coder);}}
coder是字符的编码格式,编码默认是Latin1,对应的coder是0。还有一种编码UTF16,对应的coder为1。用count(已经使用的长度)+len(要拼接的长度)得到需要的最小长度minimumCapacity。如果这个长度比原来的容量大,则触发扩容,把原数组复制到一个容量为(minimumCapacity*2+2)的新数组。在并发情况下,可能有多个线程拿到相同count,导致扩容不充分引起数组下标越界异常。一般要三个以上线程同时拿到count且必须是在程序开始时,数组不大的时候才可能出现这个异常。再来看putStringAt():
private final void putStringAt(int index, String str) {if (getCoder() != str.coder()) {inflate();}str.getBytes(value, index, coder);}
在多线程下,可能有多个线程拿到相同count,在执行getBytes时,这几个线程添加的位置是相同的,可能会发生数据覆盖的情况。StringBuilder线程安全测试示例:
@Testpublic void stringDemo02() throws InterruptedException {CountDownLatch count=new CountDownLatch(10000);StringBuilder stringBuilder=new StringBuilder();for (int i = 0; i <100 ; i++) {Thread t = new Thread(new Runnable() {@Overridepublic void run() {for (int j = 0; j <100 ; j++) {stringBuilder.append("q");count.countDown();}}});t.start();}count.await();System.out.println(stringBuilder.length());}
9912
99%的人还看了
相似问题
猜你感兴趣
版权申明
本文"StringBuilder解析":http://eshow365.cn/6-41565-0.html 内容来自互联网,请自行判断内容的正确性。如有侵权请联系我们,立即删除!