「Java 언어로 배우는 디자인 패턴 (멀티 스레드 편)」정리 (그 4)



Immutable 패턴



String 클래스에는, 캐릭터 라인의 내용을 변경하는 메소드가 준비되어 있지 않다. String의 인스턴스가 나타내고 있는 캐릭터 라인의 내용은 결코 변화하지 않는다. 이것으로부터 String 클래스의 메소드는, synchronized로 할 필요가 없다. Immutable은, 「불변의」, 「변함이 없다」라고 하는 의미. Immutable 패턴에는, 인스턴스의 상태가 변하지 않는 것이 보증되고 있는 클래스(immutable인 클래스)가 등장한다. 배타 제어가 불필요하기 때문에, 잘 이용하면 퍼포먼스 향상을 기대할 수 있다.

(코드 전체는 본서를 참조)
public final class Person {
    private final String name;
    private final String hobby;

    public Person(String name, String hobby) {
        this.name = name;
        this.hobby = hobby;
    }

    public String getName() {
        return name;
    }

    public String getHobby() {
        return hobby;
    }
}

이 클래스는 Person 클래스의 필드의 값은 생성자에서만 설정할 수 있습니다. 또 필드의 값을 변경하는 메소드도 없다. 따라서 Person 클래스의 인스턴스는 일단 만들어져 버리면 필드의 값이 바뀌지 않습니다. 이 때, 복수의 thread로부터 동시에 액세스 되어도, Person 클래스는 안전하다. 두 가지 방법 모두 synchronized 할 필요가 없습니다.

등장인부



Immutable 역이 등장한다. Immutable 역은, 필드의 값을 변경할 수 없고, 필드의 내용을 변경하는 메소드도 가지고 있지 않은 클래스.

어떤 때 사용하는지


  • 인스턴스 생성 후 상태가 변경되지 않을 때. 그것은 다음 때입니다. 필드가 final로 되어 있는 것, setter 메소드가 존재하지 않는 것, 필드가 참조하고 있는 대상의 인스턴스가 변화하지 않는 것.

  • 이하의 클래스는 immutable가 아니기 때문에 주의.
    public final class Hoge {
         private final StringBuffer hoge;
    
         public Hoge(String a, String b) {
             this.hoge = new StringBuffer("a=" + a + ", b=" + b);
         }
    
         public StringBuffer getHoge() {
             return hoge;
         }
    }
    

    getHoge 메소드로 얻을 수 있는 hoge 필드가 가지고 있는 인스턴스는, String 는 아니고, StringBuffer 의 인스턴스. StringBuffer 클래스는 내부 상태를 변경하는 메소드를 가지고 있기 때문에, hoge 필드의 내용을 외부로부터 재기록할 수 있어 버린다. hoge 필드는 final 선언되어 있기 때문에, 필드의 값 그 자체는 변화하지 않지만, 그 필드(포인터라고 생각하면 된다)가 가리키고 있는 앞에 있는 인스턴스의 상태는 변화할 가능성이 있다.
  • 인스턴스가 공유되고 자주 액세스될 때.

  • mutable 클래스와 immuatble 클래스



    Java의 표준 클래스 라이브러리에는, mutable인 클래스와 immutable인 클래스가 쌍으로 되어 있는 것이 있다. 예를 들어, StringBuffer 클래스와 String 클래스. StringBuffer는 재기록 시에는 적절하게 synchronized가 사용되고 있다. 한편 String 클래스는 Synchronized를 사용하고 있지 않기 때문에, 빠른 참조가 가능. 내용을 자주 변경한다면 StringBuffer를 사용하고, 내용을 변경할 필요가 없고 참조만 하면 String을 사용한다.

    불변성을 지키기 위해



    Immuable 패턴인 것을 전제로 synchronized를 제거하고 있는 경우, 불변성이 상실되었다고 하면(자), 클래스의 안전성까지 상실되어 버리게 되어 버린다. 그 때문에, 프로그램의 코멘트나 API 문서로, 불변성에 대해서 명기해 두어야 한다.

    관련
    「Java 언어로 배우는 디자인 패턴 (멀티 스레드 편)」정리 (그 1)
    「Java 언어로 배우는 디자인 패턴 (멀티 스레드 편)」정리 (그 2)
    「Java 언어로 배우는 디자인 패턴 (멀티 스레드 편)」정리 (그 3)

    좋은 웹페이지 즐겨찾기