String, StringBuffer, StringBuilder는 Java를 사용하면 자주 접하게 되는 문자열 클래스들이다.
String, StringBuffer, StringBuilder..... 모두 문자열을 저장하고, 관리하는 클래스인데 굳이 여러가지를 만들어놓은 이유는 무엇일까?🤔
연산이 많지 않을때는 위에 나열된 어떤 클래스를 사용하더라도 이슈가 발생할 가능성은 거의 없다. 하지만 연산횟수가 많아지거나 Multi Thread, Race condition 등의 상황이 자주 발생 한다면 각 클래스의 특징을 이해하고 상황에 맞는 적절한 클래스를 사용해주어야 한다!
*Multi Thread(멀티 쓰레드)
일반적으로 하나의 프로세서는 하나의 쓰레드를 가지고 작업을 수행한다. 멀티 쓰레드는 하나의 프로세스 내에서 둘 이상의 쓰레드가 동시에 작업을 수행하는 것을 의미한다.
*Race Condition(경쟁 상태)
다수의 프로세스나 스레드가 공유 자원을 동시에 읽거나 쓰려고 하는 상태를 의미한다.
최종 수행 결과는 프로세스들의 수행 순서에 따라 달라진다.
String과 StringBuffer/StringBuilder 클래스의 가장 큰 차이점은 String은 불변(immutable)의 속성을 갖는다는 점이다.
String str = "hello"; // String str = new String("hello");
str = str + " world"; // hello world
"hello" 값을 가지고 있던 String 클래스의 참조변수 str이 가리키는 곳에 저장된 "hello"에 "world" 문자열을 더해 "hello"가 "hello world"로 변경한 것으로 착각할 수 있다.
하지만 기존에 "hello" 값이 들어가있던 String 클래스의 참조변수 str이 "hello world"라는 값을 가지고 있는 새로운 메모리 영역을 가리키게 변경되고 처음 선언했던 "hello"로 값이 할당되어 있던 기존 메모리 영역은 Garbage로 남아있다가 GC(garbage collection)에 의해 사라지게 되는 것 이다.
String 클래스는 불변하기 때문에 문자열을 수정하는 시점에 새로운 String 인스턴스가 생성된다.
위와 같이 String은 불변성을 가지기 때문에 변하지 않는 문자열을 자주 읽어들이는 경우 String을 사용해 주시면 좋은 성능을 기대할 수 있지만 문자열 추가, 수정, 삭제 등의 연산이 빈번하게 발생하는 알고리즘에 String 클래스를 사용하면 힙 메모리(Heap)에 많은 임시 가비지(Garbage)가 생성되어 힙메모리가 부족으로 어플리케이션 성능에 치명적인 영향을 끼치게 될 수밖에 없다.
이를 해결하기 위해 Java에서는 가변(mutable)성을 가지는 StringBuffer / StringBuilder 클래스를 도입하게 된 것이다.
String 과 반대로 StringBuffer/StringBuilder 는 가변성 가지기 때문에 .append() .delete() 등의 API를 이용하여 동일 객체 내에서 문자열을 변경하는 것이 가능하다. 따라서 문자열의 추가, 수정, 삭제가 빈번하게 발생할 경우라면 String 클래스가 아닌 StringBuffer/StringBuilder를 사용해야한다.
StringBuffer sb= new StringBuffer("hello");
sb.append(" world");
🐾 한방에 정리
String - 불변(immutable)
StringBuffer, StringBuilder - 가변(mutable)
그렇다면 동일한 API를 가지고 있는 StringBuffer, StringBuilder의 차이점은 무엇일까?
가장 큰 차이점은 동기화의 유무 로써 StringBuffer 는 각 메서드별로 동기화 키워드(Synchronized Keyword)를 지원하기 때문에 멀티쓰레드 환경에서 안전(thread-safe)하다.
반대로 StringBuilder는 동기화를 지원하지 않기때문에 멀티쓰레드 환경에서 사용하는 것은 적합하지 않지만 동기화를 고려하지 않는 만큼 단일쓰레드에서의 성능은 StringBuffer 보다 뛰어나다.
🐾 한방에 정리
StringBuffer - 동기화 지원 (멀티쓰레드 환경에서 안전)
StringBuilder - 동기화 미지원 (단일쓰레드에서 좋은 성능)
🐾 한방에 정리
String - 문자열 연산이 적고 멀티쓰레드 환경일 경우
StringBuffer - 문자열 연산이 많고 멀티쓰레드 환경일 경우
StringBuilder - 문자열 연산이 많고 단일쓰레드이거나 동기화를 고려하지 않아도 되는 경우