《Java 병렬 프로그래밍 실전》 - 3

6320 단어 독서 노트

객체의 조합


4.1 설계 라인이 안전한 유형


스레드 보안 클래스를 설계하려면 다음 세 가지 기본 요소가 필요합니다.
4
  • 대상 상태를 구성하는 모든 변수를 찾아라.

  • 4
  • 구속상태 변수의 불변성 조건을 찾아낸다

  • 4
  • 객체 상태에 대한 동시 액세스 관리 정책을 설정합니다

  • 4.1.1 동기화 요구사항 수집


    대상의 불변성과 뻔뻔한 조건을 잘 모르면 라인 안전성을 확보할 수 없다.상태 변수의 유효한 값이나 상태 전환에 대한 각종 구속 조건을 만족시키려면 원자성과 봉인성에 결합해야 한다.

    4.1.2 의존 상태의 조작


    4.13 상태의 소유권


    4.2 인스턴스 닫기


    데이터를 대상 내부에 폐쇄하면 데이터의 접근을 대상의 방법에 제한할 수 있어 데이터에 접근할 때 정확한 자물쇠를 확보하기 쉽다.
    폐쇄 메커니즘은 라인 안전 클래스를 구성하기 쉽다. 폐쇄 클래스의 상태가 될 때 클래스의 라인 안전성을 분석할 때 전체 프로그램을 검사할 필요가 없기 때문이다.

    4.2.1 Java 모니터 모드


    개인 자물쇠를 통해 상태를 보호하다
    public class PrivateLock {
        private final Object myLock = new Object();
        @GuardedBy("myLock") Widget widget;
    
        void someMethod() {
            synchronized(myLock) {
                //  Widget 
            }
        }
    }

    4.2.2 실례: 차량 추적


    4.3 라인 보안 의뢰


    4.3.1 예: 위탁된 차량 추적기 기반


    4.3.2 독립된 상태 변수


    4.3.3 위탁이 효력을 상실할 때


    만약에 하나의 클래스가 여러 개의 독립적이고 라인이 안전한 상태 변수로 구성되고 모든 조작에 무효 상태 전환이 포함되지 않는다면 라인 안전성을 밑바닥의 상태 변수에 의뢰할 수 있다.
    만약 상태 변수가 라인이 안전하고 그 값을 제약하는 어떠한 불변성 조건도 없고 변수의 조작에 있어서 허용되지 않는 상태 전환도 존재하지 않는다면 이 변수를 안전하게 발표할 수 있다고 할 수 있다.

    4.4 기존 스레드 보안 클래스에 기능 추가


    "Vector를 확장하고""없으면 추가""방법을 추가합니다."
    @TheadSafe
    public class BetterVector<E> extends Vector<E> {
        public synchronized boolean putIfAbsent(E x) {
            boolean absent = !contains(x);
            if(absent) {
                add(x)
            }
            return absent;
        }
    }

    '확장' 방법은 클래스에 코드를 직접 추가하는 것보다 취약합니다. 왜냐하면 현재의 동기화 정책은 여러 개의 단독 유지보수된 원본 코드 파일에 분포되기 때문입니다.

    4.4.1 클라이언트 잠금 메커니즘


    비현상 안전한"없으면 추가"(이렇게 하지 마세요)
    @NotThreadSafe
    public class ListHelper<E> {
        public List list = Colletions.synchronizedList(new ArrayList());
    
        pblic synchronized boolean putIfAbsent(E x) {
            boolean absent = list.contains(x);
            if(absent)
                list.add(x);
            return absent;
        }
    }

    모든 체인 작업이 synchronized로 성명되었음에도 불구하고 다른 자물쇠를 사용했습니다.(list 자체 잠금 및 ListHelper 객체 잠금)
    클라이언트 잠금을 통해 '없으면 추가' (라인 보안)
    @ThreadSafe
    public class ListHelper<E> {
        public List list = Colletions.synchronizedList(new ArrayList());
    
        pblic boolean putIfAbsent(E x) {
            synchronized(list) {
            boolean absent = list.contains(x);
            if(absent)
                list.add(x);
            return absent;
            }
        }
    }

    4.4.2 조합


    조합을 통해 "없으면 추가"
    @ThreadSafe
    public class ImporvedList<T> implements List<T> {
        private final List list;
    
        public ImprovedList(List list) { this.list = list;}
    
        public synchronized boolean putIfAbsent(T x) {
            boolean contains = list.contains(x);
            if (contains)
                list.add(x);
            return !contains;
        }
    
        public synchronized void clear() {
            lsit.clear();
        }
    
        // ...  List 
    }

    사실상, 우리는 자바 모니터 모드를 사용하여 기존의List를 봉인하고, 클래스에서 밑바닥List를 가리키는 유일한 외부 인용만 있으면 라인 안전성을 확보할 수 있습니다.

    4.5 동기화 정책 문서화


    문서에서 클라이언트 코드가 알아야 할 라인 보안 보증과 코드 인원이 알아야 할 동기화 전략을 설명한다.

    좋은 웹페이지 즐겨찾기