一、源码分析StringBuffer与StringBuilder的区别
1、StringBuffer是多线程安全的,StringBuilder是多线程不安全的
多线程安全指的是 多个线程同时对一个对象进行append 等操作,不会出现覆盖、丢失的情况。
看下StringBuffer是如何做到多线程安全的:
StringBuffer类中除了构造方法,几乎所有方法都加了synchronized关键字来保证线程安全。
相对来说StringBuilder就要任性的多:
2、性能问题「JDK1.8」
理论上 不加锁的方法肯定比加锁的方法要快,但在单线程场景下 应该说是两者差距不大了,因为 synchronized 在高版本jdk里经过了偏向锁的优化,性能接近单线程了。
但是toString方法要注意了,在单线程场景下多次调用toString方法,StringBuffer性能更高,因为它使用了缓存,而StringBilder没有使用缓存
3、内存占用问题
在多次调用toString 方法场景下,StringBuffer占用内存更少,因为使用了字符数组缓存共享,而StringBuilder没有使用缓存共享
4、toString()实现原理对比
这个方法最终是要调用的,看看有啥区别
1)StringBuffer实现
由源码可以看出,不管调用多少次toString 方法,始终只会在第一次进行一次字符数组复制,之后就是共享,内存不会有大的变化(String对象是新的,但是内容一直在共享)
2)StringBuilder实现
由源码可以看出,每调一次toString 方法,都会进行字符数组复制,产生一个崭新的String对象。在某些场景下可能出现内存占用问题。
二、实际使用中注意事项
由源码分析可知,对于较大的字符串拼接场景,toString方法使用不当,内存占用峰值会有很大差异
1、对StringBuffer而言toString()调用时机不同,内存峰值持续时间会有较大差异
假设需要一个方法来拼接一个大的字符串:
实现方式1:
实现方式2:
仔细体会这两种写法,思考内存变化情况
2、对StringBuilder而言toString()重复调用问题,如果不及时释放,内存占用会持续升高
对StringBuilder而言,除了1中提到的问题,还有一个内存不断升高问题
关注吕哥,关注代码质量