String 字符串常量,是不可变的对象,因此在每次对String类型进行改变的时候其实都等于生成了一个新的String对象,然后将指针指向新的String对象,所以经常性改变内容的字符串最好不要使用String,因为每次生成对象,都会对系统性能产生影响,特别当内存中的引用对象多了以后,JVM的GC就会开始工作,那样速度是一定会相当慢的。
StringBuffer是可变的字符序列,且线程是安全的,它是一个类似于String的字符串缓冲区,是不能修改的,但通过某些方法的调用是可以改变该序列的长度和内容。可将缓冲区安全地用于多个线程,可在必要的时候对这些方法进行同步,StringBuffer对方法加了同步锁或者对调用的方法加了同步锁,因此该顺序与所涉及的每个线程进行的方法调用顺序一致的,主要操作是append()和insert(),每个方法都能有效地将给定的数据转换成字符串,然后将该字符串的字符追加或插入到字符串缓冲区中。Append方法始终将这些字符添加到缓冲区的末端,而insert方法则在指定的点添加字符。
StringBuilder也是可变的字符序列,但是线程是不安全的,它是在Android 5.0以后新增的,此类提供一个与StringBuffer兼容的API,但不保证同步。这个类用作StringBuffer的一个简易替换,用在字符串缓冲区被单个线程使用的时候。如果可能,建议优先采用该类,因为在大多数实现中,它比StringBuffer要快,两者的方法基本相同。
为什么说String线程安全?StringBuffer线程安全?StringBuilder线程不安全?
因为 String类是final 修饰的char[] 数组; 而 final 涉及到java内存管理的final域,final域拥有内存屏障,可以保证对java指令重排序的限制。保证多线程的安全。
线程安全意味着对StringBuffer类创建的对象执行方法时,对其进行上锁 .其很多方法都加了 synchronized , 也就是同时刻只能有一个线程去执行一个方法 .关键的获取长度 , 增加以及其它 , 都是加了锁的 .所以是线程安全的 ,但是 它的效率不高
stringbuilder是线程不安全的,因为stringbuilder继承了父类abstractstringbuilder的append方法,该方法中有一个count+=len的操作不是原子操作,所以在多线程中采用stringbuilder会丢失数据的准确性并且会抛ArrayIndexOutOfBoundsException的异常