자바
[Java]String과 StringBuilder, StringBuffer 차이/예제
Awdsd
2020. 5. 5. 01:15
반응형
String과 StringBuilder, StringBuffer는 같은 기능을 하는데 어떤 차이점이 있을지 궁금해서 조사해봤다.
String
- String은 객체 하나가 생성이 되면 메모리공간이 고정
- String객체를 append등으로 값을 바꾸면 새로운 String 객체를 만들어 변경된 값을 넣고 참조
- 기존 객체가 제거되면 Garbage Collection이 회수
- 문자열 연산이 많을 때 성능 좋지 않음
String 예제
public class Example {
public static void main(String[] args) {
String a = "awd";
System.out.println(a.hashCode()); //a객체의 주소
System.out.println("awd".hashCode()); //a와 똑같은 문자열의 주소
a = "zxc"; //a의 문자열 변경
System.out.println(a.hashCode()); //a객체의 주소
}
}
결과
97006
97006
121061
StringBuilder, StringBuffer
StringBuilder와 StringBuffer는 String과 다르게 문자열 연산으로 객체 공간이 부족한 경우, 기존 버퍼크기를 늘린다.
그럼 StringBuffer와 StringBuilder의 차이점은 뭘까?
- StringBuffer는 동기화 보장 -> 멀티쓰레드 환경에 적합
- StringBuilder는 동기화 보장하지 않음 -> 단일쓰레드 환경에 적합
- 동기화 기능추가로 많은 연산시 StringBuilder가 성능이 더 좋음
예제
같은 코드에 StringBuilder와 StringBuffer를 넣었을 때 두개의 차이를 살펴보자
//StringBuffer를 사용했을 경우
package example;
import java.sql.*;
public class Example implements Runnable {
StringBuffer strBuilder;
public Example() {
strBuilder = new StringBuffer();
}
@Override
public void run() {
for (int i = 0; i < 50000; i++) {
addChar();
}
}
public void addChar() {
try {
strBuilder.append("A");
strBuilder.append("A");
strBuilder.append("A");
strBuilder.deleteCharAt(0);
strBuilder.append("A");
strBuilder.append("A");
strBuilder.append("A");
for (int i = 0; i < 4; i++) {
strBuilder.deleteCharAt(0);
}
//모두 실행되면 1개의 문자가 추가된다
} catch (ArrayIndexOutOfBoundsException e) {}
}
public static void main(String[] args) {
Example strBldrWthThrdDmobj1 = new Example();
//두개의 쓰레드가 모두 실행되면 문자열의 길이는 100000이 돼야정상
Thread threadOne = new Thread(strBldrWthThrdDmobj1, "Thread One");
Thread threadTwo = new Thread(strBldrWthThrdDmobj1, "Thread Two");
threadOne.start(); //쓰레드
threadTwo.start(); //쓰레드
try {
threadOne.join();
threadTwo.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Length: " + strBldrWthThrdDmobj1.strBuilder.length());
}
}
결과
Length: 100000
//StringBuilder 사용했을 경우
package example;
import java.sql.*;
public class Example implements Runnable {
StringBuilder strBuilder;
public Example() {
strBuilder = new StringBuilder();
}
@Override
public void run() {
for (int i = 0; i < 50000; i++) {
addChar();
}
}
public void addChar() {
try {
strBuilder.append("A");
strBuilder.append("A");
strBuilder.append("A");
strBuilder.deleteCharAt(0);
strBuilder.append("A");
strBuilder.append("A");
strBuilder.append("A");
for (int i = 0; i < 4; i++) {
strBuilder.deleteCharAt(0);
}
//모두 실행되면 1개의 문자가 추가된다
} catch (ArrayIndexOutOfBoundsException e) {}
}
public static void main(String[] args) {
Example strBldrWthThrdDmobj1 = new Example();
//두개의 쓰레드가 모두 실행되면 문자열의 길이는 100000이 돼야정상
Thread threadOne = new Thread(strBldrWthThrdDmobj1, "Thread One");
Thread threadTwo = new Thread(strBldrWthThrdDmobj1, "Thread Two");
threadOne.start(); //쓰레드
threadTwo.start(); //쓰레드
try {
threadOne.join();
threadTwo.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Length: " + strBldrWthThrdDmobj1.strBuilder.length());
}
}
결과
Length: 95454
둘의 결과를 보면 StringBuffer는 정확히 100000값이 나왔지만 StringBuilder는 그보다 적은 값이 나왔다.
이 결과를 통해 StringBuffer가 동기화를 보장한다는 것을 알 수 있다.
반응형