StringBuilder 和 StringBuffer 的区别

发布于 2024-10-14 00:11:55 字数 95 浏览 3 评论 0 原文

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

What is the main difference between StringBuffer and StringBuilder?
Is there any performance issues when deciding on any one of these?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(30

缪败 2024-10-21 00:11:56

String 是一个不可变对象,这意味着值无法更改,而 StringBuffer 是可变的。

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

A String is an immutable object which means the value cannot be changed whereas StringBuffer is mutable.

The StringBuffer is Synchronized hence thread-safe whereas StringBuilder is not and suitable for only single-threaded instances.

夜还是长夜 2024-10-21 00:11:56

StringBuilder 是比 StringBuffer 因为它没有同步

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

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毫秒的数量>StringBuffer 与 StringBuilder753 毫秒 相比。

StringBuilder is faster than StringBuffer because it's not synchronized.

Here's a simple benchmark test:

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);
        }
    }
}

A test run gives the numbers of 2241 ms for StringBuffer vs 753 ms for StringBuilder.

聽兲甴掵 2024-10-21 00:11:56

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

操作“几乎”相同,但在单个线程中使用同步方法就有点矫枉过正了。

差不多就是这样了。

引用自 StringBuilder API

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

因此我们决定替代它。

VectorArrayList 也发生了同样的情况。

Basically, StringBuffer methods are synchronized while StringBuilder are not.

The operations are "almost" the same, but using synchronized methods in a single thread is overkill.

That's pretty much about it.

Quote from StringBuilder API:

This class [StringBuilder] provides an API compatible with StringBuffer, but with no guarantee of synchronization. This class is designed for use as a drop-in replacement for StringBuffer in places where the string buffer was being used by a single thread (as is generally the case). Where possible, it is recommended that this class be used in preference to StringBuffer as it will be faster under most implementations.

So it was made to substitute it.

The same happened with Vector and ArrayList.

你的笑 2024-10-21 00:11:56

但是需要借助示例来了解明显的差异吗?

StringBuffer 或 StringBuilder

只需使用 StringBuilder 除非您确实尝试在线程之间共享缓冲区。 StringBuilder 是原始同步 StringBuffer 类的非同步(更少的开销 = 更高效)的弟弟。

StringBuffer首先。 Sun 关心所有情况下的正确性,因此他们将其设为同步以使其线程安全,以防万一。

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

由于 StringBuilderStringBuffer直接替代,无需同步,因此任何示例之间都不会有差异。

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

But needed to get the clear difference with the help of an example?

StringBuffer or StringBuilder

Simply use StringBuilder unless you really are trying to share a buffer between threads. StringBuilder is the unsynchronized (less overhead = more efficient) younger brother of the original synchronized StringBuffer class.

StringBuffer came first. Sun was concerned with correctness under all conditions, so they made it synchronized to make it thread-safe just in case.

StringBuilder came later. Most of the uses of StringBuffer were single-thread and unnecessarily paying the cost of the synchronization.

Since StringBuilder is a drop-in replacement for StringBuffer without the synchronization, there would not be differences between any examples.

If you are trying to share between threads, you can use StringBuffer, but consider whether higher-level synchronization is necessary, e.g. perhaps instead of using StringBuffer, should you synchronize the methods that use the StringBuilder.

孤者何惧 2024-10-21 00:11:56

StringBuffer 是同步,StringBuilder 不是。

StringBuffer is synchronized, StringBuilder is not.

那请放手 2024-10-21 00:11:56

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

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

synchronized(同步)的含义
当某些事物被同步时,多个线程可以访问并修改它,而不会出现任何问题或副作用。
StringBuffer 是同步的,因此您可以在多个线程中使用它而不会出现任何问题。

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

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

First lets see the similarities:
Both StringBuilder and StringBuffer are mutable. That means you can change the content of them, with in the same location.

Differences:
StringBuffer is mutable and synchronized as well. Where as StringBuilder is mutable but not synchronized by default.

Meaning of synchronized (synchronization):
When some thing is synchronized, then multiple threads can access, and modify it with out any problem or side effect.
StringBuffer is synchronized, so you can use it with multiple threads with out any problem.

Which one to use when?
StringBuilder : When you need a string, which can be modifiable, and only one thread is accessing and modifying it.
StringBuffer : When you need a string, which can be modifiable, and multiple threads are accessing and modifying it.

Note : Don't use StringBuffer unnecessarily, i.e., don't use it if only one thread is modifying and accessing it because it has lot of locking and unlocking code for synchronization which will unnecessarily take up CPU time. Don't use locks unless it is required.

画中仙 2024-10-21 00:11:56

在单线程中,由于 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!

因此,构建器比缓冲区更快,并且比字符串连接快得多。
现在让我们为多个线程使用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<T extends Appendable> 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 毫秒相比,您可以放心地假设 StringBuffers 附加在使用多线程时会变慢。原因是 JIT/热点/编译器/某些东西在检测到不需要检查锁时会进行优化。

但是使用 StringBuilder,您会遇到 java.lang.ArrayIndexOutOfBoundsException,因为并发线程会尝试在不应该添加的地方添加内容。

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

In single threads, StringBuffer is not significantly slower than StringBuilder, thanks to JVM optimisations. And in multithreading, you can't use safely a StringBuilder.

Here is my test (not a benchmark, just a test) :

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));
}

Results :
strings: 319740
Buffers : 23
Builder : 7 !

So Builders are faster than Buffers, and WAY faster than strings concatenation.
Now let's use an Executor for multiple threads :

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<T extends Appendable> 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);
    }
}

Now StringBuffers take 157 ms for 100000 appends. It's not the same test, but compared to the previous 37 ms, you can safely assume that StringBuffers appends are slower with multithreading use. The reason is that the JIT/hotspot/compiler/something makes optimizations when it detects that there is no need for checking locks.

But with StringBuilder, you have java.lang.ArrayIndexOutOfBoundsException, because a concurrent thread tries to add something where it should not.

Conclusion is that you don't have to chase StringBuffers. And where you have threads, think about what they are doing, before trying to gain a few nanoseconds.

你爱我像她 2024-10-21 00:11:56

StringBuffer

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

因此它不允许两个线程同时访问同一个方法。每个方法一次只能由一个线程访问。

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

StringBuffer的值是可以改变的,这意味着它可以被赋予新的值。如今这是一个最常见的面试问题,以上类别之间的差异。
字符串缓冲区可以通过使用转换为字符串
toString() 方法。

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

输入图像描述这里

资源:字符串与 StringBuffer 与 StringBuilder

StringBuffer

StringBuffer is mutable means one can change the value of the object . The object created through StringBuffer is stored in the heap . StringBuffer has the same methods as the StringBuilder , but each method in StringBuffer is synchronized that is StringBuffer is thread safe .

because of this it does not allow two threads to simultaneously access the same method . Each method can be accessed by one thread at a time .

But being thread safe has disadvantages too as the performance of the StringBuffer hits due to thread safe property . Thus StringBuilder is faster than the StringBuffer when calling the same methods of each class.

StringBuffer value can be changed , it means it can be assigned to the new value . Nowadays its a most common interview question ,the differences between the above classes .
String Buffer can be converted to the string by using
toString() method.

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 is same as the StringBuffer , that is it stores the object in heap and it can also be modified . The main difference between the StringBuffer and StringBuilder is that StringBuilder is also not thread safe.
StringBuilder is fast as it is not thread safe .

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

enter image description here

Resource: String Vs StringBuffer Vs StringBuilder

停滞 2024-10-21 00:11:56

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

来自 Javadocs

StringBuilder类提供了与StringBuffer兼容的API,但不保证同步。此类设计为在单个线程使用字符串缓冲区的地方(通常是这种情况)用作 StringBuffer 的直接替代品。如果可能,建议优先使用此类而不是 StringBuffer,因为在大多数实现下它会更快。

StringBuilder was introduced in Java 1.5 so it won't work with earlier JVMs.

From the Javadocs:

StringBuilder class provides an API compatible with StringBuffer, but with no guarantee of synchronization. This class is designed for use as a drop-in replacement for StringBuffer in places where the string buffer was being used by a single thread (as is generally the case). Where possible, it is recommended that this class be used in preference to StringBuffer as it will be faster under most implementations.

一萌ing 2024-10-21 00:11:56

很好的问题

,我注意到以下是差异:

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.

常见的事情:-

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

Pretty Good Question

Here are the differences, i have noticed :

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.

Common thing :-

Both have same methods with same signatures. Both are mutable.

×纯※雪 2024-10-21 00:11:56

StringBuffer

  • 同步,因此线程安全
  • 线程安全,因此速度慢

StringBuilder

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

StringBuffer

  • Synchronized hence threadsafe
  • Thread safe hence slow

StringBuilder

  • Introduced in Java 5.0
  • Asynchronous hence fast & efficient
  • User explicitly needs to synchronize it, if he wants
  • You can replace it with StringBuffer without any other change
是你 2024-10-21 00:11:56

StringBuilder 不是线程安全的。字符串缓冲区是。更多信息此处

编辑:至于性能,在 hotspot 启动后,StringBuilder 是赢家。然而,对于小迭代,性能差异可以忽略不计。

StringBuilder is not thread safe. String Buffer is. More info here.

EDIT: As for performance , after hotspot kicks in , StringBuilder is the winner. However , for small iterations , the performance difference is negligible.

浮世清欢 2024-10-21 00:11:56

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

良好用法的示例:

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

StringBuilder and StringBuffer are almost the same. The difference is that StringBuffer is synchronized and StringBuilder is not. Although, StringBuilder is faster than StringBuffer, the difference in performance is very little. StringBuilder is a SUN's replacement of StringBuffer. It just avoids synchronization from all the public methods. Rather than that, their functionality is the same.

Example of good usage:

If your text is going to change and is used by multiple threads, then it is better to use StringBuffer. If your text is going to change but is used by a single thread, then use StringBuilder.

千紇 2024-10-21 00:11:56

String 是不可变的。

StringBuffer 是一个可变且同步的。

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

String is an immutable.

StringBuffer is a mutable and synchronized.

StringBuilder is also mutable but its not synchronized.

情深缘浅 2024-10-21 00:11:56

javadoc 解释了其中的区别:

此类提供了与 StringBuffer 兼容的 API,但不保证同步。此类设计为在单个线程使用字符串缓冲区的地方(通常是这种情况)用作 StringBuffer 的直接替代品。如果可能,建议优先使用此类而不是 StringBuffer,因为在大多数实现下它会更快。

The javadoc explains the difference:

This class provides an API compatible with StringBuffer, but with no guarantee of synchronization. This class is designed for use as a drop-in replacement for StringBuffer in places where the string buffer was being used by a single thread (as is generally the case). Where possible, it is recommended that this class be used in preference to StringBuffer as it will be faster under most implementations.

究竟谁懂我的在乎 2024-10-21 00:11:56

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

阅读 教程< /a> 了解更多详细信息。

StringBuilder (introduced in Java 5) is identical to StringBuffer, except its methods are not synchronized. This means it has better performance than the latter, but the drawback is that it is not thread-safe.

Read tutorial for more details.

绝情姑娘 2024-10-21 00:11:56

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

    }
}

A simple program illustrating the difference between StringBuffer and 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");
        }

    }
}
凶凌 2024-10-21 00:11:56

StringBuffer 和 StringBuilder 之间的区别 来源:

在此处输入图像描述

Difference between StringBuffer and StringBuilder Source:

enter image description here

橘虞初梦 2024-10-21 00:11:56

最好使用 StringBuilder,因为它不是同步,因此可以提供更好的性能。 StringBuilder 是旧版 StringBuffer直接替代品

Better use StringBuilder since it is not synchronized and offers therefore better performance. StringBuilder is a drop-in replacement of the older StringBuffer.

清浅ˋ旧时光 2024-10-21 00:11:56

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

StringBuffer is synchronized, but StringBuilder is not. As a result, StringBuilder is faster than StringBuffer.

岁吢 2024-10-21 00:11:56

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

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

StringBuffer
is mutable. It can change in terms of length and content. StringBuffers are thread-safe, meaning that they have synchronized methods to control access so that only one thread can access a StringBuffer object's synchronized code at a time. Thus, StringBuffer objects are generally safe to use in a multi-threaded environment where multiple threads may be trying to access the same StringBuffer object at the same time.

StringBuilder
The StringBuilder class is very similar to StringBuffer, except that its access is not synchronized so that it is not thread-safe. By not being synchronized, the performance of StringBuilder can be better than StringBuffer. Thus, if you are working in a single-threaded environment, using StringBuilder instead of StringBuffer may result in increased performance. This is also true of other situations such as a StringBuilder local variable (ie, a variable within a method) where only one thread will be accessing a StringBuilder object.

夜声 2024-10-21 00:11:56

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

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

StringBuffer is used to store character strings that will be changed (String objects cannot be changed). It automatically expands as needed. Related classes: String, CharSequence.

StringBuilder was added in Java 5. It is identical in all respects to StringBuffer except that it is not synchronized, which means that if multiple threads are accessing it at the same time, there could be trouble. For single-threaded programs, the most common case, avoiding the overhead of synchronization makes the StringBuilder very slightly faster.

妖妓 2024-10-21 00:11:56

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.

String-Buffer

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

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

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.

String-Buffer

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

It is recommended to use StringBuilder whenever possible because it is faster than StringBuffer. However, if the thread safety is necessary, the best option is StringBuffer objects.

沐歌 2024-10-21 00:11:56

StringBuffer:

  • 多线程
  • 同步
  • 比StringBuilder慢

StringBuilder

  • 单线程
  • 不同步
  • 比以往String更快

StringBuffer:

  • Multi-Thread
  • Synchronized
  • Slow than StringBuilder

StringBuilder

  • Single-Thread
  • Not-Synchronized
  • Faster than ever String
北城孤痞 2024-10-21 00:11:56

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

Since StringBuffer is synchronized, it needs some extra effort, hence based on perforamance, its a bit slow than StringBuilder.

林空鹿饮溪 2024-10-21 00:11:56

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

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

There are no basic differences between StringBuilder and StringBuffer, only a few differences exist between them. In StringBuffer the methods are synchronized. This means that at a time only one thread can operate on them. If there is more than one thread then the second thread will have to wait for the first one to finish and the third one will have to wait for the first and second one to finish and so on. This makes the process very slow and hence the performance in the case of StringBuffer is low.

On the other hand, StringBuilder is not synchronized. This means that at a time multiple threads can operate on the same StringBuilder object at the same time. This makes the process very fast and hence performance of StringBuilder is high.

久随 2024-10-21 00:11:56

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

The major difference is StringBuffer is syncronized but StringBuilder is not.If you need to use more than one thread , then StringBuffer is recommended.But, as per the execution speed StringBuilder is faster than StringBuffer , because its not syncronized .

抽个烟儿 2024-10-21 00:11:56

检查StringBuffer的同步append方法和StringBuilder的非同步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;
}

由于追加是同步的,因此与 StrinbBuilder 相比,StringBuffer 具有性能开销多线程场景。只要您不在多个线程之间共享缓冲区,就可以使用 StringBuilder,由于附加方法中缺少 synchronized,因此速度很快。

Check the internals of synchronized append method of StringBuffer and non-synchronized append method of StringBuilder.

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;
}

Since append is synchronized, StringBuffer has performance overhead compared to StrinbBuilder in multi-threading scenario. As long as you are not sharing buffer among multiple threads, use StringBuilder, which is fast due to absence of synchronized in append methods.

尐偏执 2024-10-21 00:11:56

这是String vs StringBuffer vs StringBuilder的性能测试结果。最终,StringBuilder 赢得了测试。请参阅下面的测试代码和结果。

代码

private static void performanceTestStringVsStringbuffereVsStringBuilder() {
// String vs StringBiffer vs StringBuilder performance Test

int loop = 100000;
long start = 0;

// String
String str = null;
start = System.currentTimeMillis();
for (int i = 1; i <= loop; i++) {
  str += i + "test";
}
System.out.println("String - " + (System.currentTimeMillis() - start) + " ms");

// String buffer
StringBuffer sbuffer = new StringBuffer();
start = System.currentTimeMillis();
for (int i = 1; i <= loop; i++) {
  sbuffer.append(i).append("test");
}
System.out.println("String Buffer - " + (System.currentTimeMillis() - start) + " ms");

// String builder
start = System.currentTimeMillis();
StringBuilder sbuilder = new StringBuilder();
for (int i = 1; i <= loop; i++) {
  sbuffer.append(i).append("test");
}
System.out.println("String Builder - " + (System.currentTimeMillis() - start) + " ms");

  }

在 ideone 上执行我

结果

100000 次迭代用于添加单个文本

String - 37489 ms
String Buffer - 5 ms
String Builder - 4 ms

用于添加单个文本 10000 次迭代

String - 389 ms
String Buffer - 1 ms
String Builder - 1 ms

Here is the performance testing result for String vs StringBuffer vs StringBuilder. Finally, StringBuilder won the Test. See below for test code and result.

Code:

private static void performanceTestStringVsStringbuffereVsStringBuilder() {
// String vs StringBiffer vs StringBuilder performance Test

int loop = 100000;
long start = 0;

// String
String str = null;
start = System.currentTimeMillis();
for (int i = 1; i <= loop; i++) {
  str += i + "test";
}
System.out.println("String - " + (System.currentTimeMillis() - start) + " ms");

// String buffer
StringBuffer sbuffer = new StringBuffer();
start = System.currentTimeMillis();
for (int i = 1; i <= loop; i++) {
  sbuffer.append(i).append("test");
}
System.out.println("String Buffer - " + (System.currentTimeMillis() - start) + " ms");

// String builder
start = System.currentTimeMillis();
StringBuilder sbuilder = new StringBuilder();
for (int i = 1; i <= loop; i++) {
  sbuffer.append(i).append("test");
}
System.out.println("String Builder - " + (System.currentTimeMillis() - start) + " ms");

  }

Execute Me on ideone

Result:

100000 iteration for adding a single text

String - 37489 ms
String Buffer - 5 ms
String Builder - 4 ms

10000 iteration for adding a single text

String - 389 ms
String Buffer - 1 ms
String Builder - 1 ms
坦然微笑 2024-10-21 00:11:56
  • StringBuffer 是线程安全的,但 StringBuilder 不是线程安全的。
  • StringBuilder 比 StringBuffer 更快。
  • StringBuffer 是同步的,而 StringBuilder 不是
    同步。
  • StringBuffer is thread-safe but StringBuilder is not thread safe.
  • StringBuilder is faster than StringBuffer.
  • StringBuffer is synchronized whereas StringBuilder is not
    synchronized.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文