[Java] String, StringBuilder, StringBuffer

gobeul·2023년 9월 17일
0

CS

목록 보기
2/4
post-thumbnail

자바에서 문자열을 저장하고 관리할 수 있는 클래스는 대표적으로 3개가있다.
String, StringBuilder, StringBuffer
왜 굳이 3개나 있을까? 각 클래스의 차이가 뭐지??

알아보자!


왜 구분해야 되는거지??

연산 횟수가 적다면 사실 어떤걸 써도 관계가 없다.
하지만 연산 횟수가 많아지거나, 멀티쓰레드, Race condition 등의 상황이 자주 일어나는 코드라면??

💡 Race condition
공유 자원에 대해 여러 프로세스가 동시에 접근을 시도할 때, 타이밍이나 순서 등이 결과값에 영향을 줄 수 있는 상태

그렇다면 각 클래스의 특징을 알고 구분해서 사용할 필요가 있다.


String vs StringBuffer, StringBuilder

먼저 3가지의 클래스는 불변(immutable)의 속성을 가지냐 안가지냐에 따라 구분할 수 있다.

String 은 불변(immutable)의 속성을 가진다.

불변. 즉 변하지않는 다는 것을 무엇을 나타내는 걸까?
바로 메모리 값 자체가 변하지 않는 다는 것을 의미한다.

String str = "hello";
str += " world";

String으로 선언된 참조변수 str 은 그 값이 변하지 않는다.
하지만 + 연산을 통해 str 값이 변했다고 볼 수 있지만 처음의 str과 연산후의 str은 엄연하게 다른 객체로 봐야한다.

str += " world"str = str + " world"라고 할 수 있고 재참조가 이뤄지는 것을 알 수 있다.


그림을 보면 str이 가리키는 값이 이동하는 것을 볼 수 있고 처음 값 "hello"는 Unreachable의 상태가 되어 가비지컬렉터의 대상이 된다.

※ 한가지 재밌는 점이 있다.
String 타입의 객체를 만드는 방법은 리터럴("")을 이용하는 방법과 new String("")으로 새로운 객체를 만드는 방법이 있는데 리터럴을 이용해 만들경우 조금 특이한 일이 생긴다.

리터럴을 이용해 String을 생성할 경우 Heap영역에 String Constant Pool 에 등록되고 같은 값이라면 그림처럼 객체를 몇개를 생성하던 같은 메모리를 가리키게 된다.

실제로 == 연산을 통해 주소값을 확인해보면 아래와 같은 결과를 얻을 수 있다.


String을 지양해야 될때

많은 문자열의 + 연산이 있을때 지양하자
String의 + 연산을 실제 아래와 같은 절차를 거친다.

String str = new StringBuilder("hello").append(" world").toString();

문제는 toString() 메서드의 시간복잡도와 공간복잡도는 문자열 길이에 비례하여 커진다.
때문에 +연산으로 문자열이 길어질수록 비효율적이게 될것이다.

실제로 알고리즘 문제를 풀때 이를 체감할 수 있었다. ( 프로그래머스 - 표 편집 )

StringBuffer/StringBuilder 은 가변성을 가진다.

반대로 StringBuffer/StringBuilder 는 가변성을 가지는 객체이다. 따라서 얼마든지 문자열을 추가할 수도 있고 뺄수도 있으며 String에 비해 매우 효율적이다!

StringBuffer str = new StringBuffer("hello");
str.append(" world")

StringBuffer vs StringBuilder

StringBuffer와 StringBuilder는 동기화 부분에서 차이를 가진다.

동기화 유무

간단히 얘기하자면
StringBuffer는 동기화를 지원하며 멀티스레드 환경에서 안전하게 동작한다.
StringBuilder는 동기화를 지원하지 않아 멀티스레드 환경에서 안전하진 않지만 싱글스레드 환경에서는 StringBuffer보다 좋은 성능을 보인다.

💡 스레드 안전(Thread-Safety)

  • 스레드 안전(Thread-Satety)란 멀티 스레드 프로그래밍에서 일반적으로 어떤 함수나 변수, 혹은 객체가 여러 스레드로부터 동시에 접근이 이루어져도 프로그램의 실행에 문제가 없는 것을 말한다.
  • 하나의 함수가 한 스레드로부터 호출되어 실행 중일 때, 다른 스레드가 그 함수를 호출하여 동시에 함께 실행되더라도 각 스레드에서의 함수의 수행 결과가 옳바르게 나오는 것을 말한다.

즉, 두 개 이상의 스레드가 race condition에 들어가거나 같은 객체에 동시에 접근해도 연산 결과는 정합성이 보장될 수 있게 메모리 가시성이 확보된 상태

💡 메모리 가시성
멀티 스레트 환경에서는 한 스레드가 공유자원의 값을 변경했을때 바로 다음 쓰레드가 그 변경된 값을 사용할 수 있어야 한다.


참고

profile
뚝딱뚝딱

0개의 댓글

관련 채용 정보