当前位置:  开发笔记 > 编程语言 > 正文

StringBuilder和StringBuffer之间的区别

如何解决《StringBuilder和StringBuffer之间的区别》经验,为你挑选了16个好方法。

StringBuffer和之间的主要区别是StringBuilder什么?在决定其中任何一个时,是否存在任何性能问题?



1> sblundy..:

StringBuffer是同步的,StringBuilder不是.


和StringBuilder旨在替代不需要同步的StringBuffer
几乎从不需要同步.如果有人想在StringBuilder上进行同步,他们可以在实例上使用synchronized(sb){}包围整个代码块
@locka我认为StringBuffer永远不是一个好主意(除非你有一个需要它的API)http://vanillajava.blogspot.de/2013/04/why-synchronized-stringbuffer-was-never.html
混合这两者的好助记符 - BuFFer是第一个,更老,因此同步实现.较新的Builder类使用Builder模式并且是异步的.
只有我看到的StringBuffer才是输出和各种日志实用程序之类的控制台:许多线程可能会冲突输出.因为你不希望2输出混淆...但是通常在StringBuffer级别的同步太低级别,你会想要在像levelm这样的appender上进行同步,所以locka的答案是最好的,而StringBuffer应该被弃用.这将节省新手的代码审查时间.
另一个区别是`StringBuffer`可以和`Matcher#appendReplacement`一起使用,而`StringBuilder`**不能**.这是一个非常烦人的API差异,特别是因为`Matcher`不是线程安全的,所以不需要`appendReplacement`来要求同步.

2> polygenelubr..:

StringBuilder比不是StringBuffer因为它更快synchronized.

这是一个简单的基准测试:

public class Main {
    public static void main(String[] args) {
        int N = 77777777;
        long t;

        {
            StringBuffer sb = new StringBuffer();
            t = System.currentTimeMillis();
            for (int i = N; i --> 0 ;) {
                sb.append("");
            }
            System.out.println(System.currentTimeMillis() - t);
        }

        {
            StringBuilder sb = new StringBuilder();
            t = System.currentTimeMillis();
            for (int i = N; i > 0 ; i--) {
                sb.append("");
            }
            System.out.println(System.currentTimeMillis() - t);
        }
    }
}

一个试运行给出的数字2241 msStringBufferVS 753 msStringBuilder.


这是我第一次在循环中看到` - > 0`.我花了一点时间才意识到这意味着什么.这是实际在实践中使用的东西,而不是通常的......; 我> 0; 我 - `语法?
那个`我 - >`在语法方面真的很烦人......我起初认为它是一个箭头,因为有关ASCII艺术的评论.
其他人得出的结论不同:http://alblue.bandlem.com/2016/04/jmh-stringbuffer-stringbuilder.html.基准应该用JMH完成,而不是用简单的`main()`而且,你的基准是不公平的.没有热身.
我将字符串文字更改为更大的字体:"快速的棕色狐狸"并获得了更有趣的结果.基本上,它们的速度一样快.我实际上已经没有内存,所以我不得不删除几个七人组.说明:热点优化了同步.您基本上只是测量热点执行此操作所需的时间(可能还有一些更优化).
你需要先热身.这个测试对StringBuffer不公平.而且,如果它实际上附加了一些东西会很好.实际上,我翻了测试,并附加了一个随机字符串并得到相反的测试.可以说,那个人不能相信简单的基准.相反的表明StringBuffer更快.StringBuilder为5164,StringBuffer为3699,http://hastebin.com/piwicifami.avrasm
如果`for(int i = N; i - > 0;)`被视为派对技巧,那将是多么美好的世界

3> OscarRyz..:

基本上,StringBuffer方法是同步的,而StringBuilder不是.

这些操作"几乎"相同,但在单个线程中使用同步方法是过度的.

这几乎就是它.

从StringBuilder API引用:

此类[StringBuilder]提供与StringBuffer兼容的API,但不保证同步.此类设计用作StringBuffer的替代品,用于单个线程使用字符串缓冲区的位置(通常情况下).在可能的情况下,建议首先使用此类优先于StringBuffer,因为在大多数实现中它会更快.

因此,它取代了它.

同样的事情发生在VectorArrayList.



4> Bert F..:

但是需要在一个例子的帮助下获得明显的差异?

StringBuffer或StringBuilder

StringBuilder除非你真的试图在线程之间共享缓冲区,否则简单地使用.StringBuilder是原始同步StringBuffer类的未同步(开销较小=效率更高)的弟弟.

StringBuffer先来了.Sun在所有条件下都关注正确性,因此他们将其同步以使其成为线程安全以防万一.

StringBuilder后来来了.大多数用途StringBuffer是单线程,并且不必要地支付同步的成本.

由于StringBuilder是一个简易替换StringBuffer不同步时,就不会有任何的例子之间的差异.

如果你正在尝试线程之间共享,你可以使用StringBuffer,但考虑更高级别的同步是否是必要的,例如,也许不是使用StringBuffer的问题,您应该同步的是使用StringBuilder方法.


第一个好答案!! 重点是"除非你在线程之间共享一个缓冲区"

5> user1923551..:

首先让我们看看相似之处:StringBuilder和StringBuffer都是可变的.这意味着您可以在同一位置更改它们的内容.

差异:StringBuffer也是可变的和同步的.StringBuilder可变,但默认情况下不同步.

synchronized(同步)的含义:当某个东西同步时,多个线程可以访问,并修改它而不会出现任何问题或副作用.StringBuffer是同步的,因此您可以将它与多个线程一起使用而不会出现任何问题.

哪一个使用的时候? StringBuilder:当你需要一个可以修改的字符串时,只有一个线程正在访问和修改它.StringBuffer:当你需要一个可以修改的字符串,并且多个线程正在访问和修改它.

注意:不要不必要地使用StringBuffer,即如果只有一个线程正在修改和访问它,请不要使用它,因为它有很多锁定和解锁代码用于同步,这将不必要地占用CPU时间.除非需要,否则不要使用锁.


只想提一下StringBuffer的INDIVIDUAL方法调用是线程安全的.但是如果您有多行代码,请使用同步代码块来保证线程安全,使用一些锁定/监视器(按照惯例......).基本上,不要只是假设使用线程安全库立即保证您的程序中的线程安全!

6> Nicolas Zozo..:

在单线程中,由于JVM优化,StringBuffer并不比StringBuilder慢得多.在多线程中,您无法安全地使用StringBuilder.

这是我的测试(不是基准,只是测试):

public static void main(String[] args) {

    String withString ="";
    long t0 = System.currentTimeMillis();
    for (int i = 0 ; i < 100000; i++){
        withString+="some string";
    }
    System.out.println("strings:" + (System.currentTimeMillis() - t0));

    t0 = System.currentTimeMillis();
    StringBuffer buf = new StringBuffer();
    for (int i = 0 ; i < 100000; i++){
        buf.append("some string");
    }
    System.out.println("Buffers : "+(System.currentTimeMillis() - t0));

    t0 = System.currentTimeMillis();
    StringBuilder building = new StringBuilder();
    for (int i = 0 ; i < 100000; i++){
        building.append("some string");
    }
    System.out.println("Builder : "+(System.currentTimeMillis() - t0));
}

结果:
字符串:319740
缓冲区:23
构建器:7!

因此,构建器比Buffers更快,并且比字符串连接更快.现在让我们使用Executor进行多线程:

public class StringsPerf {

    public static void main(String[] args) {

        ThreadPoolExecutor executorService = (ThreadPoolExecutor) Executors.newFixedThreadPool(10);
        //With Buffer
        StringBuffer buffer = new StringBuffer();
        for (int i = 0 ; i < 10; i++){
            executorService.execute(new AppendableRunnable(buffer));
        }
        shutdownAndAwaitTermination(executorService);
        System.out.println(" Thread Buffer : "+ AppendableRunnable.time);

        //With Builder
        AppendableRunnable.time = 0;
        executorService = (ThreadPoolExecutor) Executors.newFixedThreadPool(10);
        StringBuilder builder = new StringBuilder();
        for (int i = 0 ; i < 10; i++){
            executorService.execute(new AppendableRunnable(builder));
        }
        shutdownAndAwaitTermination(executorService);
        System.out.println(" Thread Builder: "+ AppendableRunnable.time);

    }

   static void shutdownAndAwaitTermination(ExecutorService pool) {
        pool.shutdown(); // code reduced from Official Javadoc for Executors
        try {
            if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {
                pool.shutdownNow();
                if (!pool.awaitTermination(60, TimeUnit.SECONDS))
                    System.err.println("Pool did not terminate");
            }
        } catch (Exception e) {}
    }
}

class AppendableRunnable implements Runnable {

    static long time = 0;
    T appendable;
    public AppendableRunnable(T appendable){
        this.appendable = appendable;
    }

    @Override
    public void run(){
        long t0 = System.currentTimeMillis();
        for (int j = 0 ; j < 10000 ; j++){
            try {
                appendable.append("some string");
            } catch (IOException e) {}
        }
        time+=(System.currentTimeMillis() - t0);
    }
}

现在,StringBuffers需要157毫秒才能获得100000个附加内容.它不是相同的测试,但与之前的37 ms相比,您可以放心地假设使用多线程时StringBuffers追加速度较慢.其原因是,在JIT /热点/编译器/东西使得优化,当它检测到有没有必要检查锁.

但是使用StringBuilder,你有java.lang.ArrayIndexOutOfBoundsException,因为并发线程试图添加它不应该的东西.

结论是您不必追逐StringBuffers.在尝试获得几纳秒之前,在有线程的地方,考虑一下他们在做什么.


你忘了做"t0 = System.currentTimeMillis();" 在做StringBuilder测试之前.因此,StringBuilder显示的数字实际上是运行stringbuffer和stringbuilder测试所花费的时间.添加此行,您将看到StringBuilder在两倍时间内更快.

7> Marc Novakow..:

StringBuilder是在Java 1.5中引入的,因此它不适用于早期的JVM.

来自Javadocs:

StringBuilder类提供与StringBuffer兼容的API,但不保证同步.此类设计用作StringBuffer的替代品,用于单个线程使用字符串缓冲区的位置(通常情况下).在可能的情况下,建议首先使用此类优先于StringBuffer,因为在大多数实现中它会更快.


1.4处于使用寿命终点,因此在1.5之前几乎不值得担心.

8> Sireesh Yarl..:

很好的问题

以下是差异,我注意到:

StringBuffer: -

StringBuffer is  synchronized
StringBuffer is  thread-safe
StringBuffer is  slow (try to write a sample program and execute it, it will take more time than StringBuilder)

StringBuilder的: -

 StringBuilder is not synchronized 
 StringBuilder is not thread-safe
 StringBuilder performance is better than StringBuffer.

常见的事情: -

两者都具有相同的签名相同的方法.两者都是可变的.



9> Learning..:

StringBuilder不是线程安全的.String Buffer是.更多信息在这里.

编辑:至于性能,热点开始后,StringBuilder是赢家.但是,对于小的迭代,性能差异可以忽略不计.



10> JRomio..:

StringBuffer

同步因此线程安全

线程安全因此很慢

-

StringBuilder

在Java 5.0中引入

异步因此快速高效

如果他愿意,用户明确需要同步它

您可以替换它StringBuffer而无需任何其他更改



11> 小智..:

StringBuilderStringBuffer几乎是相同的.区别在于StringBuffer同步而StringBuilder不是.虽然StringBuilder比速度快StringBuffer,但性能差异很小.StringBuilder是SUN的替代品StringBuffer.它只是避免了所有公共方法的同步.而不是那样,他们的功能是相同的.

良好用法示例:

如果您的文本将要更改并由多个线程使用,那么最好使用它StringBuffer.如果您的文本将要更改但由单个线程使用,请使用StringBuilder.



12> Virtual..:

的StringBuffer

StringBuffer是可变的,意味着可以更改对象的值.通过StringBuffer创建的对象存储在堆中.StringBuffer与StringBuilder具有相同的方法,但StringBuffer中的每个方法都是同步的,即StringBuffer是线程安全的.

因此,它不允许两个线程同时访问同一个方法.每个方法一次可以由一个线程访问.

但由于线程安全属性,StringBuffer的性能会受到攻击,因此线程安全也有缺点.因此,当调用每个类的相同方法时,StringBuilder比StringBuffer更快.

StringBuffer值可以更改,这意味着它可以分配给新值.如今它是一个最常见的面试问题,上述课程之间的差异.可以使用toString()方法将String Buffer转换为字符串.

StringBuffer demo1 = new StringBuffer(“Hello”) ;
// The above object stored in heap and its value can be changed .

demo1=new StringBuffer(“Bye”);
// Above statement is right as it modifies the value which is allowed in the StringBuffer

StringBuilder的

StringBuilder与StringBuffer相同,即它将对象存储在堆中,也可以对其进行修改.StringBuffer和StringBuilder之间的主要区别在于StringBuilder也不是线程安全的.StringBuilder很快,因为它不是线程安全的.

StringBuilder demo2= new StringBuilder(“Hello”);
// The above object too is stored in the heap and its value can be modified

demo2=new StringBuilder(“Bye”);
// Above statement is right as it modifies the value which is allowed in the StringBuilder

在此输入图像描述

资源:String Vs StringBuffer与StringBuilder



13> 小智..:

String 是不可改变的.

StringBuffer 是一个可变和同步的.

StringBuilder 也是可变的,但它不同步.



14> skaffman..:

该javadoc的解释的区别:

此类提供与StringBuffer兼容的API,但不保证同步.此类设计用作StringBuffer的替代品,用于单个线程使用字符串缓冲区的位置(通常情况下).在可能的情况下,建议首先使用此类优先于StringBuffer,因为在大多数实现中它会更快.



15> Sébastien Le..:

StringBuilder(在Java 5中引入)是相同的StringBuffer,除了它的方法不同步.这意味着它具有比后者更好的性能,但缺点是它不是线程安全的.

阅读教程了解更多详情.



16> Kevin Lee..:

一个简单的程序,说明了StringBuffer和StringBuilder之间的区别:

/**
 * Run this program a couple of times. We see that the StringBuilder does not
 * give us reliable results because its methods are not thread-safe as compared
 * to StringBuffer.
 * 
 * For example, the single append in StringBuffer is thread-safe, i.e.
 * only one thread can call append() at any time and would finish writing
 * back to memory one at a time. In contrast, the append() in the StringBuilder 
 * class can be called concurrently by many threads, so the final size of the 
 * StringBuilder is sometimes less than expected.
 * 
 */
public class StringBufferVSStringBuilder {

    public static void main(String[] args) throws InterruptedException {

        int n = 10; 

        //*************************String Builder Test*******************************//
        StringBuilder sb = new StringBuilder();
        StringBuilderTest[] builderThreads = new StringBuilderTest[n];
        for (int i = 0; i < n; i++) {
            builderThreads[i] = new StringBuilderTest(sb);
        }
        for (int i = 0; i < n; i++) {
            builderThreads[i].start();
        }
        for (int i = 0; i < n; i++) {
            builderThreads[i].join();
        }
        System.out.println("StringBuilderTest: Expected result is 1000; got " + sb.length());

        //*************************String Buffer Test*******************************//

        StringBuffer sb2 = new StringBuffer();
        StringBufferTest[] bufferThreads = new StringBufferTest[n];
        for (int i = 0; i < n; i++) {
            bufferThreads[i] = new StringBufferTest(sb2);
        }
        for (int i = 0; i < n; i++) {
            bufferThreads[i].start();
        }
        for (int i = 0; i < n; i++) {
            bufferThreads[i].join();
        }
        System.out.println("StringBufferTest: Expected result is 1000; got " + sb2.length());

    }

}

// Every run would attempt to append 100 "A"s to the StringBuilder.
class StringBuilderTest extends Thread {

    StringBuilder sb;

    public StringBuilderTest (StringBuilder sb) {
        this.sb = sb;
    }

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            sb.append("A");
        }

    }
}


//Every run would attempt to append 100 "A"s to the StringBuffer.
class StringBufferTest extends Thread {

    StringBuffer sb2;

    public StringBufferTest (StringBuffer sb2) {
        this.sb2 = sb2;
    }

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            sb2.append("A");
        }

    }
}

推荐阅读
Life一切安好
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有