Java: String vs StringBuilder vs StringBuffer 비교


1. 개요

자바에서 문자열을 다룰 때 흔히 사용하는 세 가지 클래스인 String, StringBuilder, StringBuffer는 모두 CharSequence 인터페이스를 구현하지만, 불변성, 동기화, 성능 측면에서 명확한 차이를 보인다.

이 문서에서는 다음과 같은 관점에서 세 클래스의 차이점을 심층 분석한다.


2. String

2.1 불변 객체(Immutable)의 특징

String str = "hello";
str += " world";
// 실제로는 "hello", "hello world" 두 개의 객체가 Heap에 존재

이유

2.2 성능 및 메모리 측면

2.3 사용 예시


3. StringBuilder

3.1 가변 객체(Mutable) + 비동기 환경에 적합

StringBuilder sb = new StringBuilder("hello");
sb.append(" world");
System.out.println(sb.toString());  // hello world

3.2 주요 메서드

sb.append("a");
sb.insert(2, "x");
sb.replace(1, 3, "yz");
sb.delete(0, 2);
sb.reverse();

3.3 성능 테스트 예시

public class BuilderTest {
    public static void main(String[] args) {
        long start = System.currentTimeMillis();
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < 100_000; i++) {
            sb.append("abc");
        }
        long end = System.currentTimeMillis();
        System.out.println("StringBuilder 소요 시간: " + (end - start));
    }
}

3.4 사용 시점


4. StringBuffer

4.1 가변 객체(Mutable) + 스레드 안전(Thread-safe)

StringBuffer sb = new StringBuffer("safe");
sb.append(" thread");
System.out.println(sb);  // safe thread

4.2 내부 구조

public synchronized StringBuffer append(String str) {
    super.append(str);
    return this;
}

4.3 성능 비교

4.4 멀티스레드 예시

public class BufferThreadTest {
    static StringBuffer sb = new StringBuffer();

    public static void main(String[] args) throws InterruptedException {
        Runnable task = () -> {
            for (int i = 0; i < 1000; i++) {
                sb.append("a");
            }
        };

        Thread t1 = new Thread(task);
        Thread t2 = new Thread(task);
        t1.start(); t2.start();
        t1.join(); t2.join();

        System.out.println("최종 길이: " + sb.length());  // 2000 보장됨
    }
}

5. 성능 및 메모리 비교 요약

항목

String

StringBuilder

StringBuffer

변경 가능 여부

❌ 불변

✅ 가변

✅ 가변

동기화 지원

❌ 없음

❌ 없음

synchronized 지원

성능

느림 (매번 객체 생성)

빠름

중간 (동기화 오버헤드 존재)

메모리 효율성

낮음

높음

중간

적합한 환경

상수, 설정값, 로그 ID 등

단일 스레드 문자열 조작

멀티스레드 문자열 조작


6. 결론 및 실무 팁

StringBuilder vs StringBuffer – 언제 뭐 써야 해?

항목

StringBuilderStringBuffer

스레드 안전성

❌ 비동기(스레드 안전 아님)

✅ 동기화(synchronized, 스레드 안전)

속도

빠름

상대적으로 느림

코딩 테스트/일반 개발

✅ 단일 스레드 환경에서 최적

❌ 보통 코테에선 불필요한 오버헤드 발생

멀티스레드 환경

❌ 사용 시 동기화 문제 생길 수 있음

✅ 멀티스레드 환경에서 안전하게 사용 가능

사용 예

코딩테스트, 파일 파싱, 로그 누적, 텍스트 생성

서버에서 공유 자원 처리, 멀티스레드 로그 등

💡 JDK 1.5 이상에서는 StringBuilder를 기본으로 고려하고, 동기화가 꼭 필요한 경우에만 StringBuffer를 선택하자.





Revision #10
Created 20 May 2025 04:10:30 by Dain
Updated 20 May 2025 06:40:28 by Dain