문제: https://school.programmers.co.kr/learn/courses/30/lessons/120822
✅ 내 코드
class Solution {
public String solution(String str) {
String answer = "";
for(int i=str.length()-1; i >= 0; i--){
answer+=str.charAt(i);
}
return answer;
}
}
📌 다른풀이(1) : StringBuilder() 사용
class Solution {
public String solution(String my_string) {
StringBuilder sb = new StringBuilder(my_string);
String answer = sb.reverse().toString();
return answer;
}
}
📌 다른풀이(2) : StringBuffer() 사용
class Solution {
public String solution(String my_string) {
StringBuffer sb = new StringBuffer(my_string);
String answer = sb.reverse().toString();
return answer;
}
}
📘 String , StringBuilder, StringBuffer의 차이점
1. 불변성(Immutability)
2. 스레드 안전성(Thread Safety)
3. 성능
불변성 | 안전성 | 성능 | 추천환경 | |
String | 불변(immutable)한 클래스 | 안전함 | 문자열 조작이 빈번하게 발생하는 경우 메모리 할당과 가비지 컬렉션 비용이 증가 | 변경이 없는 단일 스레드 환경 |
StringBuilder | 가변(mutable)한 클래스 | 안전하지 않음 | 내부 배열을 조작하므로 객체 생성 비용x | 단일 스레드 환경 |
StringBuffer | 가변(mutable)한 클래스 | 안전함 | 내부 배열을 조작하므로 객체 생성 비용x 단, 동기화 메커니즘을 내부적으로 처리하기 때문에 조금 더 오버헤드가 발생할 수 있음 | 멀티스레드 환경 |
🔸 String - 불변(immutable)한 클래스
: 한 번 생성된 String 객체는 변경할 수 없기 때문에 문자열을 수정하거나 조작할 때마다 새로운 String 객체가 생성 된다.
: String의 값이 변경된것처럼 보이는 이유는 기존 문자열을 수정하는것이 아니라 내부적으로 변경된 문자열을 새롭게 만들어내기 때문이다.
: 즉, String은 문자열을 할당한 후에는 수정하지 말고 읽기만 하려는 목적을 가지고 있다.
🔸StringBuilder, StringBuffer - 가변(mutable)한 클래스
: 내부적으로 가변 크기의 문자 배열을 사용하여 문자열 조작하기 때문에 문자열을 변경할 때마다 새로운 객체를 생성하지 않고 내부 배열을 조작한다.
⭐ 스레드 안전성(Thread Safety)이란❓
: 멀티스레드 환경에서 여러 스레드가 동시에 하나의 공유된 자원을 접근하더라도 원하는 동작을 안전하게 보장하는 것을 말한다.
🔸 StringBuilder - 멀티스레드 환경에서 동시에 접근할 경우 동기화 문제가 발생할 수 있기 때문에 안전하지 않다.
🔸 StringBuffer - 여러 스레드에서 동시에 접근하더라도 안전하게 조작할 수 있도록 동기화 메커니즘을 내부적으로 제공하기 때문에 안전하다.
1. 정확성:
- 멀티스레드 환경에서도 올바른 결과를 산출한다.
- 여러 스레드가 동시에 자원에 접근하더라도 데이터 불일치, 잘못된 결과를 생성하지 않고 의도한 대로 동작한다.
2. 일관성:
- 동일한 입력과 상태에서 여러 번 실행되더라도 실행 결과가 스레드 간에 일관성을 유지하여 항상 일관된 결과를 제공한다.
3. 동기화:
- 스레드 간의 동기화를 통해 자원의 동시 접근 문제를 제어한다.
- 동기화 메커니즘을 사용하여 스레드가 상호 배타적으로 접근하도록 보장한다.
스레드 안전성을 보장하기 위해서는 공유 자원에 대한 접근을 동기화해야 합니다. 동기화 메커니즘으로는 락(lock), 세마포어(semaphore), 모니터(monitor) 등이 사용될 수 있습니다. 이를 통해 한 번에 하나의 스레드만이 공유 자원에 접근할 수 있도록 보장하고, 일관성과 정확성을 유지할 수 있습니다.
스레드 안전성은 멀티스레드 환경에서 동시성 문제를 해결하고, 데이터 불일치와 같은 오류를 방지하는 데 중요한 역할을 합니다. 스레드 안전한 코드를 작성하여 프로그램의 안정성과 성능을 유지하고, 예기치 않은 동작을 방지할 수 있습니다.
🔸 String
: 불변성으로 인해 문자열을 변경할 때마다 새로운 객체를 생성해야한다.
: 문자열을 연결하거나 수정할 때마다 새로운 String 객체가 생성되므로 메모리 사용이 늘어나서 조작이 빈번할 경우 메모리 할당과 가비지 컬렉션 비용이 증가할 수 있다.
🔸 StringBuilder
: 내부적으로 가변 크기의 문자 배열을 사용하여 문자열 조작을 수행한다.
: 문자열을 변경할 때마다 새로운 객체를 생성하지 않고 내부 배열을 조작하여 성능을 향상시킨다.
🔸 StringBuffer
: 내부 배열을 조작하므로 객체 생성 비용이 들지 않기 때문에 문자열 조작이 많은 경우 성능상 이점이 있다.
: 다만, 동기화 메커니즘을 내부에서 처리하기 때문에 오버헤드가 조금 더 발생할 수 있다.
일반적으로 단일 스레드 환경 + 문자열 조작이 필요한 경우 StringBuilder를 사용하는 것이 가장 효율적이다.
멀티스레드 환경에서 스레드 안전성이 요구되는 경우 StringBuffer를 사용한다.
String은 문자열이 변경되지 않는 경우나 스레드 안전성이 보장된 단일 스레드 환경에서 주로 사용한다.