ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Java] String / StringBuffer / StringBuilde
    ☕️ java 2023. 3. 3. 21:16

    Java에서 문자열을 다루는 대표적인 클래스로는 String, StringBuffer, StringBuilder가 있다.

     

    연산 횟수가 많아지거나 멀티스레드, Race condition 등의 상황이 발생한다면 각 클래스의 특징을 이해하고 상황에 맞는 클래스를 사용하는 것이 중요하다!!

    📌 String vs StringBuffer / StringBuilder


    💡 String 과 StringBuffer / StringBuilder 클래스의 가장 큰 차이점
    • String은 불변 속성이라는 것!! 

     

    String은 불변 ❓

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

     

    위 코드에서 str이 가리키는 곳에 “hello world!” 가 저장되어 있다고 생각할 수 있다.

    하지만, 기존 “hello” 값이 들어가 있던 String str 이 “hello world!”라는 값을 가지고 있는 새로운 메모리 영역을 가리키게 변경되는 것이다!!

    처음 선언한 “hello” 값이 할당되어 있던 메모리 영역은 Garbage로 남아있다가 GC에 의해 사라진다.

    • String 클래스는 불변이기 때문에 문자열을 수정하는 시점에 새로운 String 인스턴스가 생성되는 것!!!

     

     

     

    따라서, 변하지 않는 문자열을 자주 읽는 경우에는 String을 사용하는 것이 성능이 좋다.

    하지만, 문자열을 수정하는 연산이 많이 발생하는 작업에 String 클래스를 사용하게 되면 Heap 메모리에 많은 가비지가 생성되어 성능에 좋지 않은 영향을 줄 수 있다.

     

    📖 String은 왜 불변일까?

    1. 성능
      • 문자열 리터럴을 캐싱해 재사용 시 문자열 상수 풀의 다른 문자열 변수가 동일한 개체를 참조한다.
      • 따라서, 힙 공간을 많이 절약할 수 있다.
      • String이 불변객체가 아니라면 상수 풀의 장점을 사용할 수 없다.
    2. 동기화
      • 불변 객체는 값이 바뀔 일이 없다.
      • 멀티 스레드 환경에서 thread-safe 하다는 장점이 있다.
    3. 해시코드 캐싱(Hashcode Caching)
      • 객체의 hashcode를 통해 키로 사용할 때 String은 매번 계산하지 않고 생성 단계에서 캐싱을 한다.
      • 해시코드를 캐싱할 수 있는 이유는 String이 불변하기 때문이다.

    📖 문자열 상수 풀

    • Java는 문자열 상수 풀 또는 문자열 풀이라는 특수한 저장 공간이 있다.
    • Java의 힙 영역에 존재
    • 문자열 리터럴이 생성될 때마다 JVM은 해당 문자열이 문자열 상수 풀에 존재하는지 확인
    • 존재하지 않는다면, 해당 문자열을 문자열 상수 풀에 저장하고 존재하면 저장하지 않는다.

    자세한 내용은 다음에 작성할 예정..

     

    StringBuffer / StringBuilder

    불변인 String 클래스의 문제점을 해결하기 위한 가변성(mutable)을 가지는 StringBuffer와 StringBuilder클래스가 있다.

     

    📍 StringBuffer / StringBuilder는 가변성을 가진다.

    • append()
    • delete()

    등의 API를 이용해 동일 객체에서 문자열을 변경하는 것이 가능하다.

     

    따라서, 문자열의 수정, 추가, 삭제등이 자주 발생하는 상황이라면 StringBuffer/ StringBuilder를 사용하는 것이 좋다.

     

     

    StringBuffer sb = new StringBuffer("hello");
    sb.append(" world!");

     

    📌 StringBuffer vs StringBuilder


    이 둘의 차이점은 무엇일까 😒

    💡 동기화의 유무 ⭐
      - StringBuffer는 동기화 키워드를 지원해 멀티스레드 환경에서 안전하다 (thread-safe)
      - StringBuilder는 동기화를 지원하지 않아 멀티스레드 환경에 적합하진 않다.
        하지만 단일스레드에서 성능은 StringBuffer보다 뛰어나다.

    StringBuffer는 여러 개의 스레드에서 하나의 StringBuffer 객체를 처리해도 전혀 문제가 없다.

    • StringBuffer는 메서드에서 synchronized 키워드를 사용한다.

    StringBuilder는 단일 스레드에서만 안정성을 보장한다.

     

    📖 synchronized

    • 공유 데이터에 lock을 걸어 작업 중이던 스레드가 마칠 때까지 다른 스레드에게 제어권이 넘어가지 않게 보호
    • synchronized 블록의 작업이 끝나면 lock이 풀리고 다른 스레드가 접근가능해진다.
    • 교착상태에 빠질 수 있으니 조심해야 한다.

     

    ❗String 클래스도 불변성을 가지기 때문에 멀티스레드 환경에서 안전하다(thread-safe)

     

    참고자료

    https://ifuwanna.tistory.com/221

    https://devlog-wjdrbs96.tistory.com/247

    https://velog.io/@heoseungyeon/StringBuilder와-StringBuffer는-무슨-차이가-있는가

     

    '☕️ java' 카테고리의 다른 글

    [Java] 실수 표현 - 고정소수점, 부동소수점  (0) 2023.03.07
    BigDecimal ❓  (0) 2023.03.07
    [Java] Static 과 Final  (0) 2023.03.03
    Reflection API ?  (0) 2023.02.09
    커스텀 validation 만들기  (0) 2023.01.28

    댓글

Designed by Tistory.