欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

【java】关于StringBuffer和StringBuilder的理解

程序员文章站 2022-06-01 11:53:22
...

应用

StringBuffer和StringBuilder都可以用来构建字符串,与String类一样,内部都维护一个char数组,但是String类里的char数组是使用final关键字修饰的,所以不可变。
【java】关于StringBuffer和StringBuilder的理解

区别

StringBuffer是线程安全的,StringBuilder是线程不安全的,StringBuffer的操作使用synchronized关键字加锁,从而保证了多线程情况下的线程安全。

StringBuilder线程不安全的样例

/**
 * @author 阳光大男孩!!!
 */
public class StringbuilderTest {
    public static void main(String[] args) throws InterruptedException {
        StringBuilder stringBuilder = new StringBuilder();
        int cnt=0;
        for(int i=0;i<10;i++)
        {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    for(int j=0;j<1000;j++)
                    {
                        stringBuilder.append("a");
                    }
                }
            }).start();
        }
        Thread.sleep(1000);
        System.out.println(stringBuilder.length());

    }
}

执行结果是9997,明显这是一个错误的数据。当然不一定是9997,因为多线程的结果不是必现的,即不可预测的。

首先,StringBuilder类继承自AbstractStringBuilder类,AbstractStringBuilder类有两个我们需要注意的变量,分别是字符数组value和字符数组的使用情况count.
【java】关于StringBuffer和StringBuilder的理解

这个继承就很关键,StringBuilder也就拥有从父类-AbstractStringBuilder类继承过来的数据结构.当我们上面示例代码中多线程去调用StringBuilder的append方法时,会使用super关键字去执行父类也就是AbstractStringBuilder类的append方法
【java】关于StringBuffer和StringBuilder的理解
继续看父类的append方法
【java】关于StringBuffer和StringBuilder的理解
第一行进行了判空操作,第四行确保数组的长度够用,第五行的作用则在于将新加进来的字符串加到value字符数组中。
【java】关于StringBuffer和StringBuilder的理解
导致我们上面示例程序错误的是count+=len这一步,这一步并非原子操作,当多线程同时执行这个方法的时候,就会导致数据错误的问题。

总结

在单线程的环境下,可使用StringBuilder,而在多线程,例如网络编程的情况下还是要用StringBuffer的。