StringBuilder和StringBuffer的区别

StringBuilder和StringBuffer都继承自AbstractStringBuilder类,StringBuffer是线程安全的,StringBuilder是线程不安全的。StringBuilder相对于StringBuffer速度更快。

StringBuilder为什么线程不安全?
StringBuilder类的append()方法:


image.png

StringBuilder的append()方法重写了父类AbstractStringBuilder类的append()方法,并且方法内部调用了父类的append()方法。
AbstractStringBuilder类的append()方法:


image.png

问题就在于append()方法内调用的ensureCapacityInternal(count + len)方法,count为AbstractStringBuilder的成员变量,len是追加字符串的长度。AbstractStringBuilder有两个成员变量:
image.png

value是一个字符数组,用于存储组成字符串的字符,count表示字符数组中已存储的字符数。在创建StringBuilder或StringBuffer类的对象时会初始化value的容量,默认是16。
image.png

image.png

image.png

image.png

image.png

image.png

若追加的字符串长度加上count(字符数组中已用字符数量)大于value的长度,则需要对value继续扩容,扩容的实质是创建一个新的更大容量的数组,并将原来数组中的元素复制到新的数组当中。

判断容量是否够用,不够用就要扩容:


image.png

扩容的规则为原来数组的长度的两倍再加2,若还是不够,则直接返回count与追加字符串长度的和:


image.png

在多线程的环境下,若两个线程同时进行append操作,count与追加字符串的和刚好等于value数组的长度,通过ensureCapacityInternal方法判断无需扩容,若其中一个线程先进行了追加操作,另外一个线程则不能再进行追加操作。

那么StringBuffer是如何保证线程安全的呢?


image.png

因为StringBuffer类在重写这些方法时都使用了synchronized。

你可能感兴趣的:(StringBuilder和StringBuffer的区别)