Java에서 문자를 데이터에 담고싶다면 제일 많이 쓰는 것이 String 자료형 입니다.
이 String 자료형을 써서 문자를 더하는 함수를 만들고 있었는데 이런 로직에서는 StringBuffer나 StringBuilder를 쓰는 것이 더 효율적이라는 걸 알았습니다.
셋 다 문자열을 쓰는 자료형인데 어느 부분에서 그렇게 차이나는지 궁금해졌습니다.
먼저 String에 대해 살펴보겠습니다. 제일 많이 사용하는 문자열 클래스이죠.
자바의 String 클래스는 불변성을 가집니다. 즉, 한번 생성된 String 객체는 그 값이 변하지 않습니다.
이런 특성 때문에 '+' 연산자나 concat 메서드를 통해 기존 문자열에 다른 문자열을 추가하면, 실제로는 새로운 String 객체가 생성되고 해당 객체에 연결된 문자열이 저장됩니다.
이렇게 기존 문자열에 변화를 주는 것이 아니라 새로운 객체를 계속 생성하기 때문에, 문자열 연산이 많은 경우 성능이 떨어지게 됩니다.
그래서, 자바는 이러한 문제를 해결하기 위해 내부적으로 StringBuilder 클래스를 사용합니다.
문자열에 '+' 연산을 사용하면, 컴파일 전에 자바는 내부적으로 StringBuilder 클래스를 만들어 문자열 연산을 처리합니다.
예를들어 "hello" + "world"라는 문자열은 사실 상
new StringBuilder("hello").append("world").toString()
와 같이 처리되는 것 입니다.
그래서 String은 StringBuilder를 사용해
String -> StringBuilder -> String
이런 식으로 재연산 되는 과정을 거치기 때문에 성능이 떨어지게 됩니다.
다음으론 StringBuffer와 StringBuilder를 함께 살펴 보겠습니다.
두 클래스 다 문자열 연산을 처리할때 유리한 특징이 있고 같은 매서드를 사용할 수 있습니다.
그렇다면 왜 나뉘는 걸까요?
둘의 차이점은 동기화 존재 여부에 있습니다.
StringBuffer 클래스는 각 메서드에 Synchronized Keyword가 포함되어 있습니다. 이 키워드의 존재는 멀티스레드 환경에서 동기화를 하게 해줍니다.
예를 들어, 하나의 스레드가 append() 메서드를 수행 중일 때, 다른 스레드는 대기 상태에 놓이게 됩니다. 즉, 하나의 스레드만이 메서드를 실행 할 수 있게 되며, 이는 순차적인 실행을 보장합니다.
이런 패턴 덕분에 StringBuffer는 멀티 스레드 환경에서도 안전하게 동작 할 수 있습니다.
반면에 StringBuilder 클래스는 동기화를 보장하지 않습니다. 즉, 여러 스레드가 동시에 메서드를 실행 할 수 있게 하며, 이것 때문에 데이터의 일관성이 깨질 수 있습니다.
하지만 동기화를 하지 않게 되서 StringBuffer 보다 성능이 더 좋습니다.
정리하자면 동기화가 필요한 곳에는 StringBuffer를
동기화를 고려할 필요가 없는 환경에서는 조금 더 성능이 좋은 StringBuilder를 사용하는 것이 좋습니다.
출처:https://12bme.tistory.com/42
https://inpa.tistory.com/entry/JAVA-%E2%98%95-String-StringBuffer-StringBuilder-%EC%B0%A8%EC%9D%B4%EC%A0%90-%EC%84%B1%EB%8A%A5-%EB%B9%84%EA%B5%90