前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >StringBuilder与StringBuffer

StringBuilder与StringBuffer

原创
作者头像
开源日记
修改2021-01-28 09:34:45
3850
修改2021-01-28 09:34:45
举报
文章被收录于专栏:JVMGCJVMGC

StringBuilder

代码语言:txt
复制
package com.keytech.task;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;

//线程不安全
public class StringExample1 {

    public static Integer clientTotal=5000;
    public static Integer threadTotal=200;
    public static StringBuilder stringBuilder=new StringBuilder();

    public static void main(String[] args) throws  Exception{
        ExecutorService executorService = Executors.newCachedThreadPool();
        final Semaphore semaphore=new Semaphore(threadTotal);
        final CountDownLatch  countDownLatch=new CountDownLatch(clientTotal);
        for (int i = 0; i < clientTotal; i++) {
            executorService.execute(()->{
                try{
                    semaphore.acquire();
                    update();
                    semaphore.release();

                }catch (Exception e){
                    e.printStackTrace();
                }
                countDownLatch.countDown();
            });
        }
        countDownLatch.await();
        executorService.shutdown();
        System.out.println("size"+stringBuilder.length());

    }

    private static void update() {
        stringBuilder.append("1");
    }

}

//size:4999

main函数中输出的结果不为预期的5000,并且每次结果可能会不一致,因此StringBuilder是线程不安全类

StringBuffer

代码语言:txt
复制
package com.keytech.task;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
//线程安全
public class StringExample2 {

    public static Integer clientTotal=5000;
    public static Integer threadTotal=200;
    
    public static StringBuffer stringBuffer=new StringBuffer();

    public static void main(String[] args)  throws Exception{
        ExecutorService executorService = Executors.newCachedThreadPool();
        final Semaphore semaphore=new Semaphore(threadTotal);
        final CountDownLatch countDownLatch=new CountDownLatch(threadTotal);

        for (int i = 0; i < clientTotal; i++) {
             executorService.execute(()->{
                 try{
                     semaphore.acquire();
                     update();
                     semaphore.release();

                 }catch (Exception e){
                     e.printStackTrace();
                 }
                 countDownLatch.countDown();
             });
        }
        countDownLatch.await();
        executorService.shutdown();
        System.out.println("size:"+stringBuffer.length());


    }

    private static void update() {
        stringBuffer.append("1");
    }
}

//size:5000

StringBuffer每次输出的结果与预期结果一致,因此它是线程安全的类

StringBuffer使用synchronized保证线程安全

代码语言:txt
复制
 @Override
 public synchronized StringBuffer append(String str) {
   toStringCache = null;
   super.append(str);
   return this;
 }

总结

通过以上两个例子可以知道,StringBuffer为线程安全类,StringBuilder为线程不安全类。 StringBuffer在方法的实现上使用了synchronized关键字对方法进行同步,因此是线程安全的,而StringBuilder则没有进行特殊的同步或并发处理。

StringBuffer使用了同步锁,同一时间只能有一个线程进行访问,因为在系统性能会有损耗,适用于多线程环境下使用。通常情况下,字符串拼接出现在方法内(在方法中以局部变量的方式使用,可以做到线程封闭),使用StringBuilder进行字符串的拼接会大大提高性能,属于堆栈封闭,单个线程的操作对象,因此不存在线程不安全问题,优先选择使用StringBuilder。两种字符串拼接类分别适用不同的场景,这就是为什么JAVA同时提供了这两种类。

wx.jpg
wx.jpg

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • StringBuilder
  • StringBuffer
  • StringBuffer使用synchronized保证线程安全
  • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档