String, StringBuilder, StringBuffer

GoldenDusk·2023년 11월 13일
0

CS지식

목록 보기
14/26
post-thumbnail

String, StringBuilder, 그리고 StringBuffer는 Java에서 문자열을 다루기 위한 클래스

🥕 String

  1. 불변성 (Immutability)
  • String은 불변하는 문자열을 나타낸다.
  • String 객체에 저장된 문자열은 생성된 후에 변경할 수 없다.
  • 문자열을 수정하는 것처럼 보이는 모든 작업은 사실상 새로운 String 객체를 생성한다.
  1. 효율성
  • 불변성 때문에 String은 문자열 연산이 많은 경우 비효율적일 수 있다.
  • 예를 들어, 반복적인 문자열 연결은 매번 새로운 String 객체를 생성하기 때문에 메모리 사용과 성능에 부담을 줄 수 있다.
  • 메모리 공간의 낭비가 발생하고 성능이 떨어진다.
  1. 보안과 스레드 안전
  • 불변성은 String을 스레드 안전(thread-safe)하게 만듭니다.
  • 또한, 보안 관련 코드에서 중요한 정보(예: 비밀번호)를 다룰 때 변경 불가능하다는 점이 유리할 수 있다.
  • JDK 1.5 이후부터는 컴파일 타임에 StringBuilder로 변경한다고 한다.
  • 불변 객체이기 때문에 멀티 쓰레드 환경에서 동기화를 신경쓰지 않아도 된다.
  • 문자열 연산이 적고, 조회가 많은 상황에서 쓰기 좋다.

🥕 StringBuilder, StringBuffer

StringBuilder

  1. 가변성 (Mutability)
  • StringBuilder는 가변적인 문자열을 나타낸다.
  • 이 클래스를 사용하면 기존의 문자열 내용을 변경하거나 추가할 수 있어, 반복적인 문자열 수정 작업에서 높은 성능을 제공
  1. 스레드 안전하지 않음
  • StringBuilder는 스레드 안전하지 않다.
  • 따라서 멀티 스레드 환경에서는 주의해서 사용해야 한다
  1. 성능: StringBuilderString보다 문자열 연산(추가, 수정, 삭제 등)에 있어 훨씬 효율적
  2. StringBuilder는 동기화를 고려하지 않는 상황에서 사용.(Thread를 사용하지 않는 상황.) 문자열 연산이 많은 싱글 쓰레드 환경.

StringBuffer

  1. 가변성 (Mutability): StringBufferStringBuilder와 마찬가지로 가변적인 문자열을 다룹니다. StringBuilder와 비슷한 API를 제공
  2. 스레드 안전 (Thread-Safe)
  • StringBuffer의 주요 차이점은 스레드 안전하게 설계되었다는 것
  • 이는 StringBuffer의 모든 주요 연산이 동기화(synchronized)되어 있다는 의미
  1. 성능
  • StringBufferStringBuilder에 비해 느릴 수 있다.
  • 이는 동기화로 인한 오버헤드 때문이다. 따라서 단일 스레드 환경에서는 StringBuilder가 선호
  1. StringBuffer는 동기화가 필요한 멀티 쓰레드 환경에서 사용. 문자열 연산이 많은 멀티 쓰레드 환경.

공통점

  • String과 다르게 Mutable한 객체이다.
  • 따라서 문자열 연산 시 새롭게 객체를 생성하지 않고, 처음에 만든 객체를 이용해 연산하고 크기를 변경시켜 문자열을 변경한다.
  • 따라서 문자열 연산이 자주 발생하는 상황에서 성능적으로 유리하며 쓰기 좋다.

차이점

  • StringBuilder : Thread-Safe 하지 않다. 멀티 쓰레드 지원하지 않음.
  • StringBuffer : Thread-Safe 하다. 멀티 쓰레드 지원함.
  • 즉, 동기화 지원의 유무.

🥕 스레드

멀티태스킹의 해결책 : 스레드(thread)의 특징

  1. 프로세스는 한 개 이상의 스레드 가질 수 있다.
    1. 한 프로세스 안에서 여러 개의 작업을 동시에 실행하기 위해 이 여러 개의 하나하나를 맡아 줄 것이 필요한데 그것이 스레드
  2. CPU에서 실행되는 단위(unit of execution)
    1. 예전에는 프로세스가 cpu에서 실행되는 단위였다면… 지금은 스레드가 cpu가 실행되는 단위
  3. 같은 프로세스의 스레드들끼리 컨텍스트 스위칭은 가볍다.
  4. 스레드들은 자신들이 속한 프로세스의 메모리 영역을 공유
    1. 그렇기 때문에 3번인 컨텍스트 스위칭이 가볍고
    2. 두 번째로는 같은 프로세스 안의 스레드들끼리는 데이터 공유가 쉽다.

메모리 구조 비교(싱글 스레드 vs 멀티 스레드)

💡 파란색과 녹색은 스레드들이 속한 메모리 영역

싱글 스레드

  1. 싱글 스레드를 가지는 프로세스
  2. 스레드가 나오기 전에 프로세스만의 메모리 구조

멀티 스레드

같은 프로세스를 가진 스레드들은 같은 메모리 공간을 공유하되, 스레드들 만의 고유한 영역도 있다.

  • 스레드가 등장하고 난 뒤 메모리 구조
  • 힙 메모리 영역을 공유
  • 자신의 고유한 영역이 바로 스택
  • 각각의 스레드마다 프로그램 카운터들이 따로 있음
    • 프로그램 카운터 : 다음번에 실행돼야 할 명령어가 있는 메모리 주소를 가짐

스레드 예시

  • cpu인데 코어가 2개인 cpu는 병렬적으로 스레드가 실행

🥕 멀티스레딩

개념

  • 위에서 예시든 코어가 두 개일 때 동작하는 방식
  • 하나의 프로세스가 동시에 여러 작업[스레드]을 실행하는데 목적

확장된 멀티태스킹 개념

  • 여러 프로세스와 여러 스레드가 아주 짧게 쪼개진 cpu time을 나눠 갖는 것

동기화(Synchronization)

여러 스레드가 동시에 같은 자원(예: 데이터, 객체)에 접근할 때 발생할 수 있는 충돌이나 데이터 무결성 문제를 방지하기 위한 메커니즘으로 동기화는 공유 자원에 대한 동시 접근을 제어하여, 한 시점에 하나의 스레드만이 해당 자원을 사용할 수 있게 함으로써 일관성과 안정성을 유지

동기화의 필요성

  • 데이터 무결성 보장: 여러 스레드가 동시에 데이터를 수정하려 할 때, 동기화 없이는 예측 불가능한 결과나 데이터 손상이 발생할 수 있다.
  • 경쟁 상태(또는 경합 조건) 방지: 두 개 이상의 스레드가 동시에 공유 자원을 접근하려고 할 때 발생하는 문제를 방지합
  • 일관성 유지: 동기화를 통해 프로그램의 일관된 동작을 보장한다.

동기화의 구현 방법

  • 락(Lock): 공유 자원에 접근하기 전에 락을 획득하고, 접근이 끝난 후에 락을 해제한다. 이를 통해 해당 자원을 사용하는 동안 다른 스레드의 접근을 막는다.
  • 세마포어(Semaphore): 한정된 수의 스레드만이 동시에 자원에 접근할 수 있도록 허용하는 데 사용
  • 모니터(Monitor): 객체에 대한 동기화된 접근을 제공합니다. Java에서는 synchronized 키워드를 사용하여 메서드나 블록을 동기화할 수 있습니다.

Java에서의 동기화

Java에서 동기화는 주로 synchronized 키워드를 통해 이루어진다. synchronized 메서드나 블록은 한 스레드가 실행을 완료하기 전까지 다른 스레드가 해당 메서드나 블록에 접근하는 것을 막는다.

javaCopy code
public synchronized void synchronizedMethod() {
    // 공유 자원에 대한 접근
}

또는 특정 객체에 대한 락을 사용하는 동기화 블록을 사용할 수도 있다:

javaCopy code
public void method() {
    synchronized (this) {
        // 공유 자원에 대한 접근
    }
}
profile
내 지식을 기록하여, 다른 사람들과 공유하여 함께 발전하는 사람이 되고 싶다. gitbook에도 정리중 ~

0개의 댓글