[자바 병렬 프로 그래 밍] 대상 조합

14304 단어 JavaReadingNote
대상 조합 을 통 해 수 요 를 만족 시 킬 수 있 는 라인 안전 유형 을 소개 한다.노트 는 자바 병발 프로 그래 밍 실전 에서 왔 다.
모니터 모드 (인 스 턴 스 폐쇄)
자바 모니터 모드 를 따 르 는 대상 은 대상 의 모든 가 변 상 태 를 밀봉 하고 대상 의 내 장 된 자물쇠 로 보호 합 니 다.예:
public calss PrivateLock {
	private final Object myLock = new Object();
	Widget widget;
	
	void someMethod() {
		synchronized(myLock) {
			//do something with widget
		}
	}
}

스 레 드 보안 의뢰
스 레 드 보안 의뢰 란 클래스 의 구성원 변수 가 모두 스 레 드 가 안전 하 다 면 전체 스 레 드 안전성 은 클래스 의 구성원 변수 에 의뢰 할 수 있 습 니 다.물론 의뢰 후 이 대상 은 라인 이 안전 한 지 상황 을 보고 정 해 야 한다.
  • 구성원 변수 간 에 상호작용 이 없 거나 변형 되 지 않 는 조건 의 제약 이 없 을 때 이 종 류 는 스 레 드 안전 으로 나타 날 수 있다.예 를 들 어
    public class VisualComponet{
    	private final List<Listener> list = new CopyOnWriteArrayList<Listener>();
    	
    	public void addListener(Listener listener) {
    		list.add(listener);
    	}
    }
    
    
  • 상태 변수 사이 에 일부 변형 되 지 않 는 조건 이 존재 할 때 의뢰 는 효력 을 잃 습 니 다. 즉, 클래스 는 라인 이 안전 하지 않 습 니 다.예 를 들 어
    public class NumberRange {
    	//       lower < upper
    	private final AtomicInteger lower = new AtomicInteger(0);
    	private final AtomicInteger upper = new AtomicInteger(0);
    	
    	public void setLower(int i) {
    		if	(i <= upper.get()) {
    			lower.set(i);
    		}
    	}
    }
    
    setLower 방법 에서 먼저 검 사 를 한 다음 에 값 을 부여 하 는 것 은 원자 적 인 것 이 아니 라 물론 스 레 드 안전성 에 문제 가 생 길 수 있다.

  • 기 존 스 레 드 보안 클래스 에 기능 추가
    자바 라 이브 러 리 에는 많은 유용 한 기초 모듈 이 있 습 니 다. 새로운 클래스 를 만 드 는 것 이 아니 라 기 존 클래스 를 다시 사용 하 는 것 을 우선 선택해 야 합 니 다.
  • 스 레 드 안전 류 를 계승 하여 추가 적 인 작업 을 실현 합 니 다. 예 를 들 어 vector 를 계승 하여 '존재 하지 않 으 면 추가' 하 는 작업 을 실현 합 니 다.
    public class BetterVector extends Vector {
    	public synchronized boolean putIfAbsent(Object o) {
    		boolean absent = ! contains(o);
    		if	(absent) add(x)
    		return absent;
    	}
    }
    
  • 이용 Collections.synchronizedList() 실현
    public class ListHelper {
    	public List<E> list = new Collections.synchronizedList(new ArrayList<>);
    	
    	public boolean putIfAbsent(Object o) {
    	 	synchronized(list) {
    	 		boolean absent = ! contains(o);
    			if	(absent) add(x)
    			return absent;
    	 	}
    	}
    } 
    
    여기 서 주의해 야 할 것 이 있 습 니 다. putIfAbsent 획득 한 자 물 쇠 는 list 의 자물쇠 입 니 다. 간단 하고 거 칠 게 putIfAbsent 에 synchronized 를 더 하면 문제 가 있 습 니 다. 이렇게
    @NotThreadSafe  
    class BadListHelper <E> {  
        public List<E> list = Collections.synchronizedList(new ArrayList<E>());  
        public synchronized boolean putIfAbsent(E x) {  
            boolean absent = !list.contains(x);  
            if (absent)  
                list.add(x);  
            return absent;  
        }  
    } 
    
    여기 서 문 제 는 synchronized 에 대응 하 는 자물쇠 와 list 작업 에 대한 자물쇠 가 같 지 않 습 니 다. BadListHelper 의 자 물 쇠 를 얻 었 습 니 다.그러나 list 의 자 물 쇠 를 가 져 오지 않 았 습 니 다. 스 레 드 안전 문 제 는 해결 되 지 않 았 습 니 다. 다른 사람 은 당신 이 putIfAbsent 방법 을 실행 할 때 list 를 수정 할 수 있 습 니 다.
  • 조합 사용 대상
    public class ImprovedList<E> implements List<E> {
    	private final List<E> list;
    	
    	public ImprovedList(List<E> list) {
    		this.list = list;
    	}
    	
    	public synchronized boolean putIfAbsent(Object o) {
    		boolean absent = ! contains(o);
    		if	(absent) add(x)
    		return absent;
    	}
    	
    	...
    }
    
  • 여기 에는 Collections.synchronizedList()CopyOnWriteArrayList 가 관련 되 어 있다.이 두 가지 에 대해 서 는 소스 코드 연구 의 차 이 를 살 펴 보고 블 로 그 를 전문 적 으로 쓴다.

    좋은 웹페이지 즐겨찾기