2014년 1월 16일 목요일

java concurrency in practice ch 4 Composing Objects

4.1 Designing a Thread-safe class

The design process for a thread-safe class should include these basic elements:
1. Identify the variables that form the object's state
2. Identify the invariants that constrain the state variables
3. Establish a policy for managing concurrent access to the object's state

thread safe 클래스를 만들기위해서는 아래 3개의 기본 규칙을 따라야 한다.
1. 오브젝트의 상태를 구성할 변수들을 식별한다.
2. 상태 변수들을 제약할 불변 조건들을 식별한다.
3. 오브젝트의 상태들에 병렬로 접근하는 것을 관리한 규칙을 세운다.

if they are all primitive type, the field comprise the entire state
if the object has fields that are reference to other objects. its state will encompass field from the referenced objects as well

오브젝트의 필드가 기본 타입이면 이 필드들이 전체 상태를 구성한다.
하지만 오브젝가 레퍼런스 필드를 가지고 있으면 상태는 레퍼런스 오브젝트가 가지고 있는 모들 필드를 포함 해야 한다.

The synchronization police defines how an object coordinates access to its state without violating its invariants or post-condition. it specifies what combination of immutability, thread confinement and locking is used to maintain thread safety

동기화 정책은 오브젝트가 불변 및 이후 조건을 침범하지 않고 오브젝트의 상태값에 조화롭게 접근 하는 방법을 정의한다.

불변성, 쓰레드 제약, 락킹이 합쳐져서 쓰레드 세이프티를 이룬다.

4.1.1 Gathering Synchronization Requirements
Making a class thread-safe mean ensuring its invariants hold under concurrent access;
this require reasoning about its state objects and variables have a state space

클래스를 쓰레드 세이프로 만드는것은 병렬접근에서 이 클래스의 값들이 적법한 값을 가져야 함을 의마한다. 해당 사항을 만족하기 위해서 상태 변수들의 상태 범위에 대한 값을 알아햐 한다.

Invariants?
Many class have invariants that identify certain states as valid or invalid
많은 클래스들은 적법함을 가지고 있다 적법함 이란 상태 변수의 값이 적절한가 아니면 적절하지 않는가 이다. 예를 들어 long 으 적절한 값은  Long.MIN~ Long.MAX 까지이다

post-condition?
operations may have post-conditions that identify certain state transitions as invalid
동작은 상태값의 변화가 적절하지 않음을 식별 할 수 있는다 post-condtion을 가질 수 있다
예를들어 count 가 17 이면 다음은 18 이 되어야 하는 경우가 있다 즉 전의 값에 의존하는
값을 가질 수 있다

you cannot ensure thread safety without understanding an object's invariants and post-conditions. Constraints on the valid values or state transitions for state variables can create atomicity and encapsulation requirements

오브젝트의 적법함과 이후 조건 에 대해서 이해하지 못한다면 쓰레드 세이프하게 만들 수없다

상태 변수들을 적법하게 만드는 제약조건들을 위해서  원자성이나 encapsulation 이 필요 할 수 도 있다

4.1.2 State-dependent Operations
state based precondition are called state dependent
empty queue 에서 remove 할 수 없다 이와 같은걸 precondition 이라고 한다.

싱글 쓰레드 프로그램에서는 프리컨디션이 되지 않으면 실패한다 하지만 멀티쓰레드 프로그램에서는 다른 쓰레드가 큐에다가 엘리먼트를 집어 넣을 수 있음으로 나중에 true 가 될 수 있다

wait-notify 는 사용하기 힘드므로 왠만하면 빌드인 라이블러리를 사용하자자
blockingQueue or semaphore

4.1.3 State OwnerShip

4.2 Instance Confinement
Encapsulation simplifies making classes thread-safe by promoting instance confinement,
often just called confinement. when object is encapsulated within another object, all code paths that have access to the encapsulated object are known and can be therefore be analyzed more easily than if that object where accessible to the entire program

오브젝트 안에 오브젝트를 위치하고 내부 오브젝트에 접근하는 모든 코드를 통제해서 쓰레드 세이프를 만드는걸 instance confinement 라고 한다.

Encapsulating data within an object confines access to the data to the object's methods
making it easier to ensure that the data is always accessed with the appropriate lock held

오브젝트 안에 encapsulating 된 데이터에 접근하는 메서드를 제약한다면 해당 데이터에 접근할때 언제나 적절한 락을 사용하는걸 쉽게 할 수 있다

@ThreadSafe
public class PersonSet {
    @GuardedBy("this")
    private final Set mySet = new HashSet();
    public synchronized void addPerson(Person p) {
        mySet.add(p);
}
    public synchronized boolean containsPerson(Person p) {
        return mySet.contains(p);
} }
1
위 코드를 보면  mySet 은 지금 PersonSet 에  confinement 되어 있다
HashSet 자체는 thread safe 가 아니지만 접근하는 모든 경로가 메서드에 의해 락으로 보호됨으로 쓰레드 세이프이다. 위와 같은걸 instance confinement 라고 한다

만약 Person이 mutable object라면 해당 오브젝트에서 동기화가 필요하다

예를 들어 arrayList 나 hashset 은 쓰레드 세이프가 아니다 하지만 wrapper factory 인
Collections.synchronziedList and freiend 를 이용하면 instance confinement 를 사용해 쓰레드 세이프다.

Confinement make it easier to build thread-safe classes because a class that confine its state can be analyzed for thread safety without having to examine the whole program

confinement 는 하나의 클래스만 조사해서 쓰레드 세이프임을  확인 할 수 있음으로 쓰레드 세이프를 구현하는대 편하다(사용하지 않으면 모든 프로그램을 조사해야한다)

4.2.1 the java monitor pattern

An object following the java monitor pattern encapsulates all its mutable state and guards it with the object's own intrinsic lock

자바 모니터  패턴을 따르는 오브젝트들은 그들의 mutable state 를 오브젝의 내장 락으로 보호하고 이것을 encapuslate 한다.
public class PrivateLock {
    private final Object myLock = new Object();
    @GuardedBy("myLock") Widget widget;
    void someMethod() {
        synchronized(myLock) {
} }
    // Access or modify the state of widget
}
there are advantage to using a private lock object instead of object's intrinsic lock(or any other public accessible lock)

오브젝트 내장락을 사용하지 않고 privae lock 을 사용하면 클라이언트 코드에서 락에 접근 할 수 없으므로 조금더 튼튼하게 thread safe 를 구현 할 수 있다

intrinsic lock 이란 this 에 락을 거는걸 말하는거 같다

4.2.2 Example: tracking Fleet Vehicles

4.3 Delegating Thread Safety