StringBuilder와 StringBuffer의 차이점


답변:


1665

StringBuffer동기화 StringBuilder되지 않습니다.


239
StringBuilder는 동기화가 필요하지 않은 StringBuffer를 대체하기위한 것입니다.
Joel

95
동기화는 거의 필요하지 않습니다. 누군가 StringBuilder에서 동기화하려는 경우 인스턴스의 전체 코드 블록을 동기화 된 (sb) {}로 둘러 쌀 수 있습니다
locka

23
@locka 나는 StringBuffer가 결코 좋은 아이디어가 아니라고 주장 할 것이다 (필요한 API가 없다면) vanillajava.blogspot.de/2013/04/…
Peter Lawrey

8
StringBuffer에 대한 유일한 장소는 출력 및 다양한 로깅 유틸리티와 같은 콘솔입니다. 많은 스레드가 충돌하여 출력 될 수 있습니다. 2 개의 출력을 섞지 않기를 원하지만 일반적으로 StringBuffer 수준에서 동기화하는 것이 너무 낮은 수준이므로 levelm과 같은 어 펜더에서 동기화를 원하므로 locka 응답이 가장 좋고 StringBuffer는 더 이상 사용되지 않아야합니다. 초보자는 코드 검토 시간을 절약 할 수 있습니다.
레미 모린

20
이 두 가지를 혼합하는 사람들에게 좋은 니모닉-BuFFer는 처음에 오래되었고 동기화 된 구현이었습니다. 최신 빌더 클래스는 빌더 패턴을 사용하며 비동기입니다.
Datageek

728

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

테스트 실행은 의 수를 제공 2241 ms하기위한 StringBuffer753 ms를위한 StringBuilder.


10
문자열 리터럴을 "빠른 갈색 여우"로 바꾸고 더 흥미로운 결과를 얻었습니다. 기본적으로 그들은 빠르다. 실제로 메모리가 부족하여 7을 몇 개 제거해야했습니다. 설명 : 핫스팟에 의해 동기화가 최적화됩니다. 기본적으로 핫스팟 이이 작업을 수행하는 데 걸리는 시간 (그리고 아마도 더 많은 최적화)을 측정하고 있습니다.
Jilles van Gurp

7
전에 워밍업해야합니다. 이 테스트는 StringBuffer에 불공평합니다. 또한 실제로 무언가를 추가하면 좋을 것입니다. 실제로 테스트를 뒤집어 임의의 문자열을 추가하고 반대 테스트를 받았습니다. 말하자면 간단한 벤치 마크를 신뢰할 수는 없습니다. 반대로 StringBuffer가 빠릅니다. StringBuilder의 5164
mmm

75
--> 0루프에서 처음으로 본 것입니다 . 그것이 무엇을 의미하는지 깨달을 순간을 얻었습니다. 이것이 일반적인 ...; i > 0; i--구문 대신 실제로 실제로 사용되는 것 입니까?
Raimund Krämer

19
그것은 i -->문법적으로 정말 성가신 일입니다 ... ASCII 아트에 대한 의견 때문에 처음에는 화살표라고 생각했습니다.
Sameer Puri

14
다른 사람들은 다른 결과로 결론을 내립니다 : alblue.bandlem.com/2016/04/jmh-stringbuffer-stringbuilder.html . 벤치 마크는 단순한 것이 아니라 JMH로 수행해야합니다. main()또한 벤치 마크는 불공평합니다. 워밍업이 없습니다.
Lukas Eder

249

기본적으로 StringBuffer메소드는 동기화 StringBuilder되지 않은 상태에서 동기화 됩니다.

작업은 "거의"동일하지만 단일 스레드에서 동기화 된 메소드를 사용하는 것은 과도합니다.

그것은 거의 그것에 관한 것입니다.

StringBuilder API 에서 인용 :

이 클래스 [StringBuilder]는 StringBuffer와 호환되는 API를 제공 하지만 동기화를 보장하지는 않습니다 . 이 클래스는 문자열 버퍼가 단일 스레드에 의해 사용되는 장소에서 StringBuffer를 대체하는 대체물로 사용하도록 설계되었습니다 (일반적인 경우). 가능한 경우이 클래스 는 대부분의 구현에서 더 빠를 것이기 때문에 StringBuffer 보다 우선적으로 사용하는 것이 좋습니다 .

그래서 그것을 대체하기 위해 만들어졌습니다.

동일은 무슨 일이 있었 Vector하고 ArrayList.


1
또한로 HashtableHashMap.
shmosel

176

그러나 예제의 도움으로 명확한 차이를 얻어야합니까?

StringBuffer 또는 StringBuilder

StringBuilder스레드간에 버퍼를 실제로 공유하지 않는 한 간단하게 사용하십시오 . StringBuilder원래 동기화 StringBuffer클래스 의 동기화되지 않은 (더 적은 오버 헤드 = 더 효율적인) 남동생 입니다.

StringBuffer먼저왔다. Sun은 모든 조건에서 정확성에 관심을 가졌기 때문에 만일의 경우를 대비하여 스레드 안전을 위해 동기화했습니다.

StringBuilder나중에왔다. 대부분의 용도 StringBuffer는 단일 스레드이며 불필요하게 동기화 비용을 지불했습니다.

이후 StringBuilderA는 드롭 인 교체 용은StringBuffer 동기가없는 모든 실시 예 사이의 차이가 없을 것이다.

당신이하면 되는 스레드간에 공유에 노력하고, 당신이 사용할 수있는 StringBuffer, 그러나 아마 대신 StringBuffer를 사용의 예를 들면, 높은 레벨의 동기화가 필요한지 여부를 고려, 당신은 모두 StringBuilder를 사용하는 방법을 동기화해야합니다.


14
첫 번째 좋은 답변 !! 핵심은 "쓰레드간에 버퍼를 공유하지 않는 한"
AlexWien

1
매우 상세한 답변!
Raúl

81

먼저 유사점을 살펴 보겠습니다. StringBuilder와 StringBuffer는 모두 변경 가능합니다. 즉, 동일한 위치에서 컨텐츠를 변경할 수 있습니다.

차이점 : StringBuffer도 변경 가능하고 동기화됩니다. StringBuilder는 변경 가능하지만 기본적으로 동기화되지 않습니다.

동기화의 의미 (동기화) : 어떤 것이 동기화되면 여러 스레드가 액세스하여 문제 또는 부작용없이 스레드를 수정할 수 있습니다. StringBuffer는 동기화되어 있으므로 아무 문제없이 여러 스레드에서 사용할 수 있습니다.

언제 어느 것을 사용해야합니까? StringBuilder : 수정할 수있는 문자열이 필요한 경우 하나의 스레드 만 액세스하고 수정합니다. StringBuffer : 수정이 가능한 문자열이 필요하고 여러 스레드가 액세스하고 수정하는 경우.

참고 : 불필요하게 StringBuffer를 사용하지 마십시오. 즉, 하나의 스레드 만 수정하고 액세스하는 경우 동기화에 대한 잠금 및 잠금 해제 코드가 많아 CPU 시간이 불필요하게 걸리므로 사용하지 마십시오. 필요한 경우가 아니면 잠금을 사용하지 마십시오.


2
StringBuffer의 INDIVIDUAL 메소드 호출은 스레드로부터 안전하다는 것을 언급하고 싶습니다. 그러나 여러 줄의 코드가있는 경우 동기화 된 코드 블록을 사용하여 잠금 / 모니터 (일반적으로 ...)와 함께 스레드 안전성을 보장하십시오. 기본적으로 스레드 안전 라이브러리를 사용하면 프로그램에서 스레드 안전을 즉시 보장한다고 가정하지 마십시오!
Kevin Lee

57

단일 스레드에서 StringBuffer는 StringBuilder보다 크게 느리지 않습니다. JVM 최적화 덕분에 . 그리고 멀티 스레딩에서는 안전하게 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 개 추가하십시오. 동일한 테스트는 아니지만 이전 37ms와 비교하여 멀티 스레딩 사용시 StringBuffers 추가가 더 느리다고 가정 할 수 있습니다 . 그 이유는 JIT / hotspot / compiler / something이 잠금을 확인할 필요 가 없음을 감지하면 최적화하기 때문입니다 .

그러나 StringBuilder를 사용하면 java.lang.ArrayIndexOutOfBoundsException이 발생 합니다. 동시 스레드는 원하지 않는 곳에 무언가를 추가하려고 시도하기 때문입니다.

결론은 StringBuffer를 쫓아 갈 필요가 없다는 것입니다. 그리고 스레드가있는 곳에서 몇 나노 초를 얻기 전에 그들이 무엇을하고 있는지 생각하십시오.


5
"t0 = System.currentTimeMillis ();"를 잊어 버렸습니다. StringBuilder 테스트를 수행하기 전에 따라서 StringBuilder에 표시되는 숫자는 실제로 stringbuffer AND stringbuilder test를 실행하는 데 걸린 시간입니다. 이 줄을 추가하면 StringBuilder가 두 번 빠르다는 것을 알 수 있습니다.
Gena Batsyan

참고 withString+="some string"+i+" ; ";다른 두 개의 루프에 해당하지 않고, 따라서 공정한 비교가 아닙니다.
Dave Jarvis

정확하고 수정되었습니다. 생각 문자열은 여전히 ​​매우 느립니다.
Nicolas Zozol

당신은 더 설명 할 이유 는, ArrayIndexOutOfBoundsException에 대한 인상 의 StringBuilder
알리레자 Fattahi

벤치 마크에는 JMH를 사용해야합니다. 벤치 마크가 정확하지 않습니다.
Lukas Eder

42

StringBuilder는 Java 1.5에서 도입되었으므로 이전 JVM에서는 작동하지 않습니다.

로부터 Javadoc과 :

StringBuilder 클래스는 StringBuffer와 호환되는 API를 제공하지만 동기화를 보장하지는 않습니다. 이 클래스는 문자열 버퍼가 단일 스레드에 의해 사용되는 장소에서 StringBuffer의 드롭 인 대체로 사용하도록 설계되었습니다 (일반적인 경우). 가능한 경우,이 클래스는 대부분의 구현에서 더 빠를 것이기 때문에 StringBuffer에 우선하여 사용하는 것이 좋습니다.


13
1.4는 서비스 수명이 다해 1.5 이전 버전에 대해 걱정할 필요가 없습니다.
Tom Hawtin-tackline

@ tomHawtin-tackline은 반드시 그런 것은 아닙니다. 1.4 이전에는 대부분의 사람들이 매일 사용하는 엔터프라이즈 제품이 있습니다. 또한 BlackBerry java는 1.4를 기반으로하며 여전히 최신 버전입니다.
Richard Le Mesurier

그리고 CDC와 CLDC에는이 없습니다 StringBuilder.
Jin Kwon

37

아주 좋은 질문

차이점은 다음과 같습니다.

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.

일반적인 것 :-

둘 다 동일한 서명을 가진 동일한 메소드를 가지고 있습니다. 둘 다 변경할 수 있습니다.


23

StringBuffer

  • 동기화 된 스레드 세이프
  • 따라서 스레드 안전

StringBuilder

  • Java 5.0에 도입
  • 빠르고 효율적인 비동기식
  • 원하는 경우 사용자가 명시 적으로 동기화해야합니다.
  • StringBuffer다른 변경없이 교체 할 수 있습니다

참고 : 단일 작업 만 스레드로부터 안전하고 여러 작업은 안전하지 않습니다. 예를 들어, 당신은 호출하면 append두 번이나 append하고 toString안전하지 없습니다.
Peter Lawrey

22

StringBuilder는 스레드로부터 안전하지 않습니다. 문자열 버퍼입니다. 더 많은 정보는 여기에 .

편집 : 성능면에서 핫스팟이 시작된 후 StringBuilder가 승자입니다. 그러나 작은 반복의 경우 성능 차이는 무시할 수 있습니다.


21

StringBuilderStringBuffer거의 동일합니다. 차이점은 StringBuffer동기화되고 동기화 StringBuilder되지 않는다는 것입니다. 비록 StringBuilder빨리보다 StringBuffer, 성능 차이는 거의이다. StringBuilder의 SUN을 대체 StringBuffer합니다. 모든 공개 메소드와의 동기화를 피할뿐입니다. 그보다는 기능이 동일합니다.

좋은 사용법의 예 :

텍스트가 변경되어 여러 스레드에서 사용되는 경우을 사용하는 것이 좋습니다 StringBuffer. 텍스트가 변경되지만 단일 스레드에서 사용되는 경우을 사용하십시오 StringBuilder.


19

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


모두 StringBuilder는 불변이며 문자열 유형은 변경할 수 있습니다
Brinda Rathod

Strings 및 StringBuilders가 "빠르고"그리고 StringBuffers가 "매우 느리다"는 것에 동의하지 않습니다. 위의 답변을 참조하십시오.
FireCubez

17

String 불변입니다.

StringBuffer 변경 가능하고 동기화되었습니다.

StringBuilder 또한 변경 가능하지만 동기화되지 않았습니다.


또한 StringBuffer는 스레드 안전 데이터에 액세스하기 위해 스레드를 잠그므로 작업이 느리게 진행됩니다. StringBuilder는 스레드를 잠그지 않으며 멀티 스레딩 방식으로 실행되므로 빠릅니다. 문자열-문자열을 연결할 필요가없는 경우이 방법은 좋은 방법이지만 필요한 경우 StringBuilder->를 사용합니다. String은 매번 새 Object를 힙으로 생성하지만 StringBuilder는 동일한 개체를 반환하기 때문에 ...
Musa

11

javadoc에서는 차이를 설명합니다 :

이 클래스는 StringBuffer와 호환되는 API를 제공하지만 동기화를 보장하지는 않습니다. 이 클래스는 문자열 버퍼가 단일 스레드에 의해 사용되는 장소에서 StringBuffer의 드롭 인 대체로 사용하도록 설계되었습니다 (일반적인 경우). 가능한 경우,이 클래스는 대부분의 구현에서 더 빠를 것이기 때문에 StringBuffer에 우선하여 사용하는 것이 좋습니다.


10

StringBuilder (Java 5에서 도입)은 StringBuffer 메소드가 동기화되지 않은 것을 제외하고와 합니다. 이는 후자보다 성능이 우수하지만 스레드로부터 안전하지 않다는 단점이 있습니다.

자세한 내용은 튜토리얼 을 읽으십시오 .


6

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

    }
}

4

StringBuffer는 변경 될 문자열을 저장하는 데 사용됩니다 (문자열 개체는 변경할 수 없음). 필요에 따라 자동으로 확장됩니다. 관련 클래스 : String, CharSequence.

StringBuilder는 Java 5에 추가되었습니다. StringBuffer는 동기화되지 않은 것을 제외하고는 StringBuffer와 동일합니다. 즉, 여러 스레드가 동시에 액세스하는 경우 문제가 발생할 수 있습니다. 단일 스레드 프로그램의 경우 동기화 오버 헤드를 피하는 가장 일반적인 경우로 StringBuilder가 약간 더 빠릅니다.


4
단일 스레드 프로그램은 Java에서 가장 일반적인 경우는 아니지만 StringBuilder일반적으로 메소드에 국한되며 하나의 스레드에만 표시됩니다.
finnw

4

StringBuffer동기화되었지만 동기화 StringBuilder되지 않았습니다. 결과적으로 StringBuilder보다 빠릅니다 StringBuffer.


4

StringBuffer 는 변경 가능합니다. 길이와 내용에 따라 변경 될 수 있습니다. StringBuffers는 스레드로부터 안전합니다. 즉, 한 번에 하나의 스레드 만 StringBuffer 객체의 동기화 된 코드에 액세스 할 수 있도록 액세스를 제어하는 ​​동기화 된 메서드가 있습니다. 따라서 StringBuffer 객체는 일반적으로 여러 스레드가 동일한 StringBuffer 객체에 동시에 액세스하려고하는 다중 스레드 환경에서 사용하는 것이 안전합니다.

StringBuilder StringBuilder 클래스는 액세스가 동기화되지 않아 스레드로부터 안전하지 않다는 점을 제외하면 StringBuffer와 매우 유사합니다. 동기화되지 않으면 StringBuilder의 성능이 StringBuffer보다 우수 할 수 있습니다. 따라서 단일 스레드 환경에서 작업하는 경우 StringBuffer 대신 StringBuilder를 사용하면 성능이 향상 될 수 있습니다. 이는 하나의 스레드 만 StringBuilder 객체에 액세스하는 StringBuilder 로컬 변수 (예 : 메서드 내의 변수)와 같은 다른 상황에서도 마찬가지입니다.


4

StringBuffer :

  • 멀티 스레드
  • 동기화
  • StringBuilder보다 느림

StringBuilder

  • 단일 스레드
  • 비 동기화
  • 그 어느 때보 다 빠른 문자열

2
더 정확하게, String c = a + b에 해당 String c = new StringBuilder().append(a).append(b).toString()이 빨리되지 않도록. 그것은 당신이 하나를 가질 수있을 때, 각 문자열 대입을위한 새로운 하나를 만드는 것이 단지입니다 ( String d = a + b; d = d + c;String d = new StringBuilder().append(a).append(b).toString(); d = new StringBuilder().append(d).append(c).toString();동안 StringBuilder sb = new StringBuilder(); sb.append(a).append(b); sb.append(c); String d = sb.toString();하나의 StringBuilder instanciation을 절약 할 수).
Chop

4

스트링 빌더 :

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는 개별 작업에 대해서만 스레드 안전하므로 StringBuilder를 사용하는 것이 가장 좋습니다. 여러 작업의 경우 명시 적 잠금이 필요합니다.
Peter Lawrey

4

더 나은 사용 StringBuilder이되지 않기 때문에 동기화 때문에 더 나은 성능 및 이벤트. 이전 StringBuilder드롭 인 대체 입니다 StringBuffer.


3
@Mark true이지만 대부분의 경우 StringBu(ff|ild)er단일 스레드에서만 사용되는 로컬 변수입니다.
gabuzo

1
@MarkMcKenna : 멀티 스레드 응용 프로그램에서도 외부 잠금을 사용하거나이를 피하기 위해 추가 작업을 수행해야하는 경우가 종종 있습니다. 예를 들어, 두 개의 스레드가 각각 여러 개의 문자열을 포함하는 레코드를 stringbuilder에 추가하려면 추가 할 데이터를 집계 한 다음 더 빠르더라도 단위로 추가해야합니다 (스레딩 문제 없음). 일련의 이산 추가 작업을 간단히 수행합니다.
supercat

3

이후 StringBuffer동기화되어,이 때문에 perforamance에 따라 약간의 여분의 노력을 필요로 자사는보다 느린 비트 StringBuilder.


3

StringBuilder와 사이에는 기본적인 차이점이 없으며 그 사이 StringBuffer에는 몇 가지 차이점 만 있습니다. 에서 StringBuffer방법 동기화됩니다. 이것은 한 번에 하나의 스레드 만 스레드에서 작동 할 수 있음을 의미합니다. 둘 이상의 스레드가있는 경우 두 번째 스레드는 첫 번째 스레드가 완료 될 때까지 기다려야하고 세 번째 스레드는 첫 번째 및 두 번째 스레드가 완료 될 때까지 기다려야합니다. 이로 인해 프로세스가 매우 느려져 성능 StringBuffer이 저하됩니다.

한편, StringBuilder동기화되지 않습니다. 이는 한 번에 여러 스레드가 동일한 StringBuilder객체에서 동시에 작동 할 수 있음을 의미합니다 . 이로 인해 프로세스가 매우 빨라지므로 성능 StringBuilder이 높습니다.


3

A는 String수단 불변 목적 값은 변경 될 수없는 반면StringBuffer 가변이다.

StringBuffer따라서 동기화 스레드 세이프 반면된다 StringBuilder단지 단일 스레드 인스턴스하지 적합하다.


3
StringBuffer가 코드를 동기화했다고해서 반드시 StringBuffer가 스레드 안전하다는 것을 의미하지는 않습니다. 다음 예제를 고려하십시오. StringBuffer testingBuffer = "stackoverflow"; 이제 Thread-1은 testingBuffer에 "1"을 추가하려고하고, Thread-2는 testingBuffer에 "2"를 추가하려고합니다. 이제 append () 메소드가 동기화 되었더라도 testingBuffer의 값이 "stackoverflow12"인지 "stackoverflow21"인지 확인할 수 없습니다. 실제로, Oracle은 stringbuffer보다 stringbuilder를 사용하도록 권장합니다. 나는 이것이 도움이
되었기를

2

가장 큰 차이점은 StringBuffer동기화되어 있지만 그렇지 StringBuilder않습니다. 둘 이상의 스레드를 사용해야하는 경우 StringBuffer가 권장되지만 동기화 속도 StringBuilderStringBuffer아니기 때문에 실행 속도 가보다 빠릅니다 .


4
StringBuffer는 작업을 하나만 수행하는 경우에만 스레드로부터 안전합니다. 제대로 이해하기가 어렵 기 때문에 여러 스레드에서 사용하지 않는 것이 좋습니다.
Peter Lawrey

@PeterLawrey 무슨 뜻인가요? :-)
Tamad Lang

1
@ b16db0 StringBuffer의 대부분의 사용은 외부 동기화없이 여러 번 호출하여 클래스를 무의미하게 만들므로 스레드 안전하지 않습니다.
피터 로리

@PeterLawrey 아 StringBuffer는 여전히 동기화 된 환경이 필요합니다.
Tamad Lang

2

의 동기화 된 추가 방법 StringBuffer및 동기화되지 않은 추가 방법의 내부를 확인하십시오 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;
}

APPEND이기 때문에 synchronized, StringBuffer비교의 성능 오버 헤드를 갖는다 StrinbBuilder에서 시나리오 멀티 스레딩. 여러 스레드간에 버퍼를 공유하지 StringBuilder않는 한 synchronized, append 메소드 가 없기 때문에을 사용하십시오.


1

다음은 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");

  }

이데온에서 나를 처형하라

결과 :

단일 텍스트 추가를위한 100000 반복

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

단일 텍스트 추가를위한 10000 회 반복

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

1
  • StringBuffer는 스레드로부터 안전하지만 StringBuilder는 스레드로부터 안전하지 않습니다.
  • StringBuilder는 StringBuffer보다 빠릅니다.
  • StringBuffer는 동기화되는 반면 StringBuilder는 동기화되지 않습니다.

1

StringBuffer는 동기화되어 스레드로부터 안전하며 StringBuilder는 동기화되지 않고 더 빠릅니다.


이 차이는이 질문에 대한 다른 모든 답변에서 주어졌습니다. 새로운 것을 강조해 주시겠습니까?
Nico Haase
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.