String StringBuffer和StringBuilder区别及性能

结论:

(1)如果要操作少量的数据用 String;

(2)多线程操作字符串缓冲区下操作大量数据 StringBuffer;

3)单线程操作字符串缓冲区下操作大量数据 StringBuilder(推荐使用)。

String:不可变字符串;

StringBuffer:可变字符串、效率低、线程安全(大量方法被synchronized修饰);

StringBuilder:可变字符序列、效率高、线程不安全

 参考引用文章:https://blog.csdn.net/weixin_41101173/article/details/79677982,https://blog.csdn.net/longfulong/article/details/78700239

1.性能比较

//以运算10w次来比较

package Reflect;

public class TestStringCount {

    public static void main(String[] args) {
        
        Long start = System.currentTimeMillis();
        Long end;
        String aa = "";
        for (int i = 1; i < 100000; i++) {
            aa = aa + "a";
        }
        end = System.currentTimeMillis();
        System.out.println(end - start);
        System.out.println("String usage:" + (end - start));

        start = end;
        final StringBuffer bb = new StringBuffer();
        for (int i = 1; i < 100000; i++) {
            bb.append("a");
        }
        end = System.currentTimeMillis();
        System.out.println("StringBuffer usage:" + (end - start));

        start = end;
        final StringBuilder cc = new StringBuilder();
        for (int i = 1; i < 100000; i++) {
            bb.append("a");
        }
        end = System.currentTimeMillis();
        System.out.println("StringBuilder usage:" + (end - start));
    }
}

输出:
String usage:5606
StringBuffer usage:8
StringBuilder usage:4

2.分析。

  String的值,即字符串常量,是不可变的,每次对String的操作(str=str+"a")都会在堆内存中生成新的对象(“a”),然后再连接,堆中的对象最后由GC进行回收,即每次“+”都要创建对象,拼接,以及GC不定期的回收,不仅效率低下也浪费内存空间。

BTW:堆区heap area,所有的对象和它们相应的实例变量以及数组将被存储在这里。每个JVM同样只有一个堆区。由于方法区堆区的内存由多个线程共享,所以存储的数据不是线程安全的;栈区stack area,对每个线程会单独创建一个运行时栈。对每个函数呼叫会在栈内存生成一个栈帧(Stack Frame)。所有的局部变量将在栈内存中创建。栈区是线程安全的,因为它不是一个共享资源。栈帧被分为三个子实体:局部变量数组 – 包含多少个与方法相关的局部变量并且相应的值将被存储在这里,操作数栈 – 如果需要执行任何中间操作,操作数栈作为运行时工作区去执行指令,帧数据 – 方法的所有符号都保存在这里。在任意异常的情况下,catch块的信息将会被保存在帧数据里面.除堆栈还有方法区method area,所有类级别数据将被存储在这里,包括静态变量。每个JVM只有一个方法区,它是一个共享的资源。

3.继承关系

对字符串进行修改的时候,需要使用 StringBuffer 和 StringBuilder 类。

和 String 类不同的是,StringBuffer 和 StringBuilder 类的对象能够被多次的修改,并且不产生新的未使用对象。

StringBuilder 类在 Java 5 中被提出,它和 StringBuffer 之间的最大不同在于 StringBuilder 的方法不是线程安全的(不能同步访问)。

由于 StringBuilder 相较于 StringBuffer 有速度优势,所以多数情况下建议使用 StringBuilder 类。然而在应用程序要求线程安全的情况下,则必须使用 StringBuffer 类。

三者的继承结构

原文地址:https://www.cnblogs.com/pu20065226/p/10114826.html