[Java] StringBuilder / StringBuffer

2023. 1. 23. 16:31기술 창고/Java

728x90
SMALL

String

StringBuilder / StringBuffer 와 일반적인 String 클래스의 가장 큰 차이점은 불변함(immutable)이다.

String str = "nice";
str = str + " meet you";

기본적으로 위의 코드를 살펴본다면 nice 문구에 meet you라는 문구가 붙어 변한다고 생각할 것이다.

하지만, nice 라는 문구를 가진 str 변수의 메모리와 meet you라는 문구가 추가된 str은 같은 메모리를 사용하는 것이 아니라 새로 추가되는 것이다.

 

따라서 기존의 nice만 있던 str변수는 가비지(Garbage)가 된 상태이고, 이후 GC(Garbage Collector) 로 인해 제거가 된다.

즉, 불변하기 때문에 기존의 데이터가 변경되는 것이 아니라 새로 생성이 되는 것이다.

 

이러한 불변성 떄문에 문자열에 추가, 변경과 같은 작업이 빈번하게 일어나는 로직에 String 클래스를 사용하면 많은 양의 가비지가 생성이 되어 메모리 부족 현상이 일어날 수 있다.

 

이러한 불변성의 문제점을 해결하기 위한 가변성의 특징을 가지는 StringBuffer / StringBuilder 가 존재한다.

 

 

StringBuilder

StringBuilder 는 문자열을 변경하거나 이어붙이는 작업을 수행할 경우 추가 메모리 생성없이 기존 문자열에서 확장이 가능한 클래스이다.

문자열의 상태를 빈번하게 변경하는 로직이나 알고리즘에 사용하기에 적합하다.

 

StringBuilder 는 멀티쓰레드 환경에서 문자열의 안전한 변경을 보장해주지 않는 특징이 있다.

즉, 여러 쓰레드가 문자열에 동시에 접근하여 변경 작업을 수행하면 결과가 온전치 못하다.

StringBuffer 와 다르게 동기화를 사용하지 않기 때문에 StringBuffer 보다 빠른 속도를 보여주나 그만큼 멀티쓰레드 환경에서는 안정적이지 못하다.

 

 

StringBuilder sb = new StringBuilder("test");
System.out.println(sb + " " + System.identityHashCode(sb)); //문자열과 메모리 주소 출력 

sb.append("2"); // 문자열 추가
System.out.println(sb + " " + System.identityHashCode(sb)); //문자열과 메모리 주소 출력

StringBuilder로 초기문자열을 생성하고 출력했을 때의 메모리 주소와 append를 통해 문자열을 추가한 메모리의 주소가 같다.

 

 

 

StringBuffer

StringBuffer 는 StringBuilder 클래스와 마찬가지로 가변성을 보장하는 클래스이다.

동일하게 생성한 문자열에 대해 수정과 같은 변경 작업을 수행하면 메모리를 추가 생성하는 것이 아니라 기존의 할당된 메모리를 가진 상태에서 변경이 되는 것이다.

 

StringBuilder 와의 차이점은 StringBuffer는 멀티쓰레드 환경에서 문자열의 안전한 변경을 보장해준다는 특징이다.

즉, 여러 쓰레드에서 동시에 접근해도 안정적인 결과를 얻을 수 있는 것이다.

이러한 멀티쓰레드 접근 시에도 안전한 이유는 동기화가 가능하기 때문인데, 동기화는 동시 요청이 들어오면 모든 쓰레드가 동기화 되어있기 때문에 한 쓰레드의 요청이 정상적으로 완료가 될 때까지 기다려야 하기 때문에 느리다.

 

따라서, 단일 쓰레드에서는 동기화를 고려하지 않는 StringBuilder 가 좋은 성능을 가지고, 멀티 쓰레드에서의 경우에는 StringBuffer 가 안정적인 성능을 발휘한다.

 

StringBuffer sb = new StringBuffer("test");
System.out.println(sb + " " + System.identityHashCode(sb)); //문자열과 메모리 주소 출력 

sb.append("2"); // 문자열 추가
System.out.println(sb + " " + System.identityHashCode(sb)); //문자열과 메모리 주소 출력

StringBuffer 도 마찬가지로 초기 문자열과 변경한 문자열의 메모리 주소가 같다는 것을 확인할 수 있다.

728x90
반응형
LIST