모르는게 많은 개발자

[Java]String과 StringBuilder, StringBuffer 차이/예제 본문

자바

[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가 동기화를 보장한다는 것을 알 수 있다.

반응형
Comments