StringBuilder和StringBuffer之间的区别

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

StringBuffer是同步的, StringBuilder不是。

StringBuilderStringBuffer更快,因为它没有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); } } } 

测试运行给出了StringBuffer2241 msStringBuffer 753 ms的数字。

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

操作“几乎”相同,但在单个线程中使用同步方法是过度的。

这几乎就是它。

从StringBuilder API引用:

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

所以它是替代它。

VectorArrayList

但是需要借助一个例子来获得明显的差异?

StringBuffer或StringBuilder

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

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

StringBuilder后来出现了。 StringBuffer大多数用法都是单线程,并且不必要地支付同步的成本。

由于StringBuilder是没有同步的StringBuffer 替代品 ,因此任何示例之间都不会有差异。

如果您尝试在线程之间共享,则可以使用StringBuffer ,但考虑是否需要更高级别的同步,例如,如果您同步使用StringBuilder的方法,则可能不使用StringBuffer。

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

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

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

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

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

在单线程中,由于JVM优化, StringBuffer并不比StringBuilder慢得多 。 在multithreading中,您无法安全地使用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进行multithreading:

 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相比,您可以放心地假设使用multithreading时StringBuffers追加速度较慢 。 原因是JIT / hotspot / compiler / something在检测到不需要检查锁时进行优化。

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

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

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

来自Javadocs :

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

很好的问题

以下是差异,我注意到:

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. 

常见的事情: –

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

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

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

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

良好用法示例:

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

的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

StringBuffer

  • 同步因此线程安全
  • 线程安全因此很慢

StringBuilder

  • 在Java 5.0中引入
  • 异步因此快速高效
  • 如果需要,用户明确需要同步它
  • 您可以将其替换为StringBuilder而无需任何其他更改

String是不可变的。

StringBuffer是一个可变和同步的。

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

javadoc解释了差异:

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

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

阅读教程了解更多详情。

StringBuilder比StringBuffer快得多,因为它是非同步的。

在这里,您可以更多地了解同步的成本

让我们以编程方式看看StringBuilder比StringBuffer快多少

 public class Test{ public static void main(String[] args){ long startTime = System.currentTimeMillis(); StringBuffer sb = new StringBuffer("Yasir"); for (int i=0; i<10000; i++){ sb.append("Shabbir"); } System.out.println("Time taken by StringBuffer: " + (System.currentTimeMillis() - startTime) + "ms"); startTime = System.currentTimeMillis(); StringBuilder sb2 = new StringBuilder("Yasir"); for (int i=0; i<10000; i++){ sb2.append("Shabbir"); } System.out.println("Time taken by StringBuilder: " + (System.currentTimeMillis() - startTime) + "ms"); } } 

产量

StringBuffer占用的时间:16ms

StringBuilder所用的时间:0ms

一个简单的程序,说明了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, ie * 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"); } } } 

更好地使用StringBuilder,因为它不是同步的,因此性能更好。 StringBuilder是旧StringBuffer的替代品。

StringBuffer是同步的,但StringBuilder不是。 因此, StringBuilderStringBuffer更快。

StringBuffer是可变的。 它可以在长度和内容方面发生变化。 StringBuffers是线程安全的,这意味着它们具有控制访问的同步方法,因此一次只有一个线程可以访问StringBuffer对象的同步代码。 因此,StringBuffer对象通常可以安全地在multithreading环境中使用,其中多个线程可能试图同时访问同一个StringBuffer对象。

StringBuilder StringBuilder类与StringBuffer非常相似,只是它的访问不同步,因此它不是线程安全的。 通过不同步,StringBuilder的性能可以比StringBuffer更好。 因此,如果您在单线程环境中工作,则使用StringBuilder而不是StringBuffer可能会提高性能。 对于其他情况也是如此,例如StringBuilder局部变量(即方法中的变量),其中只有一个线程将访问StringBuilder对象。

的StringBuffer

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

StringBuilder的

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

StringBuffer的:

  • multithreading
  • 同步
  • 比StringBuilder慢

StringBuilder的

  • 单线程
  • 未同步
  • 字符串比以前更快

String-Builder

 int one = 1; String color = "red"; StringBuilder sb = new StringBuilder(); sb.append("One=").append(one).append(", Color=").append(color).append('\n'); System.out.print(sb); // Prints "One=1, Colour=red" followed by an ASCII newline. 

字符串缓冲区

 StringBuffer sBuffer = new StringBuffer("test"); sBuffer.append(" String Buffer"); System.out.println(sBuffer); 

建议尽可能使用StringBuilder,因为它比StringBuffer更快。 但是,如果需要线程安全性,则最好的选项是StringBuffer对象。

StringBuffer用于存储将被更改的字符串(不能更改String对象)。 它会根据需要自动扩展。 相关类:String,CharSequence。

StringBuilder是在Java 5中添加的。它在所有方面都与StringBuffer相同,只是它没有同步,这意味着如果多个线程同时访问它,可能会有麻烦。 对于单线程程序,最常见的情况是,避免同步开销会使StringBuilder的速度稍微快一些。

StringBuilder和StringBuffer之间没有基本的区别,它们之间只存在一些差异。 在StringBuffer中,方法是同步的。 这意味着一次只有一个线程可以对它们进行操作。 如果有多个线程,则第二个线程必须等待第一个线程完成,第三个线程必须等待第一个和第二个线程完成,依此类推。 这使得该过程非常慢,因此在StringBuffer的情况下性能很低。

另一方面,StringBuilder是非同步的。 这意味着多个线程可以同时在同一个StrinBuilder对象上运行。 这使得该过程非常快,因此StringBuilder的性能很高。

由于StringBuffer是同步的,它需要一些额外的工作,因此基于perforamance,它比StringBuilder有点慢。

String是一个不可变对象,这意味着在StringBuffer可变的情况下不能更改该值。

StringBuffer是同步的,因此线程安全,而StringBuilder不适用于单线程实例。

主要的区别是StringBuffer是同步的但是StringBuilder不是。如果你需要使用多个线程,那么建议使用StringBuffer。但是,根据执行速度, StringBuilderStringBuffer更快,因为它不同步。

检查StringBuffer的synchronized append方法和StringBuffer非同步append方法的内部。

StringBuffer :

 public StringBuffer(String str) { super(str.length() + 16); append(str); } public synchronized StringBuffer append(Object obj) { super.append(String.valueOf(obj)); return this; } public synchronized StringBuffer append(String str) { super.append(str); return this; } 

StringBuilder :

 public StringBuilder(String str) { super(str.length() + 16); append(str); } public StringBuilder append(Object obj) { return append(String.valueOf(obj)); } public StringBuilder append(String str) { super.append(str); return this; } 

由于append是synchronized ,因此与multithreading场景中的StrinbBuilder相比, StringBuffer具有性能开销。 只要您不在多个线程之间共享缓冲区,请使用StringBuilder ,由于缺少append方法中的synchronized ,这很快。

此链接将使您不仅了解StringBuilderStringBuffer的概念,还了解它们与String类的关联和区别。 这将使您了解何时使用哪个类。 http://www.acquireandinspire.org/2013/01/string-string-builder-string-buffer.html