String str = "hello";
str = str + " world";
hello
값이 들어가있던 String
클래스의 참조변수 str
이 hello world
라는 값을 가지고 있는 새로운 메모리 영역을 가리키게 변경된다.hello
로 값이 할당되어 있던 메모리 영역은 Garbage로 남아있다가 GC(garbage collection)에 의해 사라지게 되는 것이다.StringBuffer
처럼 멀티스레드 환경에서 안전하다.StringBuffer sb= new StringBuffer("hello");
sb.append(" world");
.append()
.delete()
등의 API를 이용하여 동일 객체내에서 문자열을 변경하는 것이 가능하다.buffer
의 크기 설정, 버퍼 크기 줄이고 늘리며 객체 생성 속도가 느리다.동기화 키워드
(synchronized keyword)를 지원하여 멀티쓰레드 환경에서 안전하다.StringBuffer
보다 뛰어나다.멀티 스레드 프로그래밍에서 일반적으로 어떤 함수나 변수, 혹은 객체가 여러 스레드로부터 동시에 접근이 이루어져도 프로그램의 실행에 문제가 없음을 뜻한다.
Re-entrancy
어떤 함수가 한 스레드에 의해 호출되어 실행 중일 때, 다른 스레드가 그 함수를 호출하더라도 그 결과가 각각에게 올바로 주어져야 한다.
Thread-local storage
공유 자원의 사용을 최대한 줄여 "각각의 스레드에서만 접근 가능한 저장소"들을 사용함으로써 동시 접근을 막는다.
이 방식은 동기화 방법과 관련되어 있고, 또한 공유상태를 피할 수 없을 때 사용하는 방식이다.
Mutual exclusion
Thread에 lock이나 semaphore를 걸어서 공유자원에는 하나의 thread만 접근 가능하게 한다.
Atomic operations
데이터 변경시 atomic하게 데이터에 접근하도록 만든다.
Immutable Object
객체 생성 이후에 값을 변경할 수 없도록 만든다.
성능(Performance)
String
이 불변이기 때문에String Pool
도 존재할 수 있다.
자바에서는 다른 변수여도 값이 같으면 같은 객체를 참조한다. → 힙 영역 절약
public class Test {
public static void main(String[] args) {
String s1 = "Hello World";
String s2 = "Hello World";
System.out.println(s1 == s2); // true
}
}
만약 String
이 가변 객체였다면 s2
값을 변경해도 s1 == s2
이 true
로 나온다. → 객체 공유 불가능
동기화(Synchronization)
불변 객체는 값이 바뀔 일이 없기 때문에 멀티스레드 환경에서 Thread-safe하다는 장점이 있다.
해시코드 캐싱(Hashcode Caching)
String의 hashCode()
구현을 보면, 아직 hash 값을 계산한 적이 없을 때 최초 1번만 실제 계산 로직을 수행한다. 이후부터는 이전에 계산했던 값을 그냥 리턴만 하도록 되어 있다. 즉 hashCode
값을 캐싱(caching)하고 있다. → 성능 개선
public final class String {
public int hashCode() {
int h = hash;
if (h == 0 && value.length > 0) {
char val[] = value;
for (int i = 0; i < value.length; i++) {
h = 31 * h + val[i];
}
hash = h;
}
return h;
}
}
캐싱할 수 있는 이유는 String
이 불변객체이기 때문이다.
참고로 hashCode()
는 Hash
자료구조의 구현체, 예를 들면 HashMap
, HashTable
, HashSet
와 같은 클래스에서 자주 호출된다.
보안
사용자의 이름이나 패스워드, 혹은 네트워크 연결을 위한 포트 번호나 connection URL, 파일 이름 등 중요한 정보를 String
으로 받을 때가 많다. JVM의 class loader
가 class loading
을 수행할 때도 마찬가지다.
객체에 대해 보안 검사를 해도, 가변 객체라면 나중에 문자열이 변경될 가능성이 있다.
출처:
https://velog.io/@hoo00nn/Thread-safe와-동기화-객체