스 레 드 보안 과 자원 공유 (Thread Safety and Shared Resources)

원본 링크:http://tutorials.jenkov.com/java-concurrency/thread-safety.html
여러 스 레 드 에 동시에 호출 될 수 있 는 안전 코드 를 스 레 드 안전 이 라 고 합 니 다.만약 코드 가 라인 이 안전 하 다 면, 그것 은 경쟁 조건 을 포함 하지 않 을 것 이다.경쟁 조건 은 여러 스 레 드 가 공유 자원 을 변경 할 때 만 발생 한다.따라서 자바 스 레 드 가 실 행 될 때 어떤 자원 을 공유 하 는 지 알 아 보 는 것 이 중요 하 다.
국부 변수
부분 변 수 는 모든 스 레 드 자신의 스 택 에 저 장 됩 니 다. 즉, 부분 변 수 는 스 레 드 간 에 영원히 공유 되 지 않 습 니 다.즉, 모든 원생 변 수 는 스 레 드 가 안전 하 다 는 것 이다.다음은 부분 원생 변수 스 레 드 안전 한 예 입 니 다.
    public void someMethod() {
        long threadSafeInt = 0;
        threadSafeInt++;

    }

부분 개체 참조
일부 대상 의 인용 은 다소 다 르 기 때문에 인용 자 체 는 공유 되 지 않 는 다.그러나 인 용 된 대상 은 모든 스 레 드 자신의 부분 스 택 에 저 장 된 것 이 아 닙 니 다.모든 대상 은 공 유 된 더미 에 저 장 됩 니 다.만약 에 대상 이 어떤 방법 으로 체 내 에 만 들 어 졌 고 이 대상 은 이 방법 에서 벗 어 나 지 않 았 을 것 이다. 이것 은 바로 스 레 드 가 안전 한 것 이다.사실상 그것 을 다른 방법 이나 다른 대상 에 게 전달 할 수도 있 지만, 이러한 방법 이나 대상 의 다른 라인 은 접근 할 수 없다.아래 의 예 에서 부분 대상 은 스 레 드 가 안전 합 니 다.
    public void someMethod() {
        LocalObject localObject = new LocalObject();
        localObject.callMethod();
        method2(localObject);
    }

    public void method2(LocalObject localObject) {
        localObject.setValue("value");
    }

위의 예 에서 부분 대상 의 인 스 턴 스 는 방법 method 2 에 의 해 되 돌아 오지 않 았 고 someMethod () 방법 외 에 이 부분 대상 을 방문 할 수 있 는 다른 대상 에 게 전달 되 지 않 았 습 니 다.someMethod () 방법 을 실행 하 는 모든 스 레 드 는 자신의 국부 대상 인 스 턴 스 를 만 들 고 국부 대상 에 게 참조 하도록 배정 합 니 다.따라서 여기 서 부분 대상 localObject 를 사용 하 는 것 은 스 레 드 가 안전 합 니 다.사실 전체 someMethod () 방법 은 라인 이 안전 합 니 다.부분 대상 의 인 스 턴 스 localObject 가 같은 종류의 다른 방법 이나 다른 클래스 에 매개 변수 로 전달 되 더 라 도 스 레 드 가 안전 합 니 다.유일한 예 외 는 호출 방법 을 사용 할 때 국부 대상 localObject 가 매개 변수 로 저장 되면 다른 스 레 드 는 특정한 수단 으로 접근 할 수 있 습 니 다. 이런 상황 에서 이 부분 대상 은 스 레 드 가 안전 하지 않 습 니 다.
구성원 대상
구성원 대상 은 대상 에 따라 공 유 된 더미 에 저 장 됩 니 다.따라서 두 스 레 드 가 같은 대상 인 스 턴 스 의 같은 방법 을 호출 하고 구성원 대상 을 변경 하면 이 방법 은 스 레 드 가 안전 하지 않 습 니 다.아래 의 이 예 에서 의 방법 은 라인 이 안전 한 것 이 아니다.
    public class NotThreadSafe {
        StringBuilder builder = new StringBuilder();
        public void add(String text) {
            this.builder.append(text);
        }
    }

두 스 레 드 가 NotThreadSafe 류 의 같은 인 스 턴 스 에서 add () 방법 을 동시에 호출 하면 경쟁 조건 이 생 길 수 있 습 니 다.예 를 들 면:
    NotThreadSafe sharedInstance = new NotThreadSafe();
    new Thread(new MyRunnable(sharedInstance)).start;
    new Thread(new MyRunnable(sharedInstance)).start;

    public class MyRunnable implements Runnable {
        NotThreadSafe instance = null;

        public MyRunnable(NotThreadSafe instance{
            this.instance = instance;
        }
        public void run() {
            this.instance.add("some text");
        }   
    } 

두 스 레 드 의 구조 방법 을 통 해 NotThreadSafe 류 의 같은 인 스 턴 스 를 전달 하 는 방식 으로 대상 을 공유 하 였 음 을 주의 하 십시오.따라서 두 스 레 드 가 NotThreadSafe 류 의 같은 인 스 턴 스 에서 add () 방법 을 호출 하면 경쟁 조건 을 초래 할 수 있 습 니 다.
그러나 두 스 레 드 가 서로 다른 인 스 턴 스 의 add () 방법 을 동시에 호출 하면 경쟁 조건 을 초래 하지 않 습 니 다.아래 의 예 는 앞의 것 과 약간 다르다.
    new Thread(new MyRunnable(new NotThreadSafe())).start();
    new Thread(new MyRunnable(new NotThreadSafe())).start();

현재 두 스 레 드 는 모두 자신 만 의 NotThreadSafe 인 스 턴 스 가 있 기 때문에 add () 방법 을 호출 할 때 서로 영향 을 주지 않 습 니 다.따라서 대상 이 스 레 드 가 아 닌 안전 한 방식 으로 사용 하 더 라 도 경쟁 조건 을 초래 하지 않 는 다.
스 레 드 제어 탈출 규칙
코드 가 안전 한 지 아 닌 지 를 판단 하기 위해 스 레 드 제어 탈출 규칙 을 사용 할 수 있 습 니 다.
    If  a resource is created, used and disposed within the control of the same thread, and never escapes the control of this thread, the use of that resource is thread safe.

             、  、                                 ,                 。

대상, 배열, 파일, 데이터베이스 연결, socket 등 모든 공 유 된 자원 일 수 있 습 니 다.자바 에 서 는 프로그래머 의 명시 적 석방 대상 이 필요 하지 않 기 때문에 '석방 (disposed)' 은 결국 이 대상 을 사용 할 곳 이 없 거나 이 대상 의 인용 을 null 로 설정 한 다 는 뜻 이다.
한 대상 에 대한 사용 이 스 레 드 가 안전 하 더 라 도 이 대상 이 공 유 된 자원, 예 를 들 어 파일 이나 데이터 베 이 스 를 가리 키 면 전체 로 서 응용 프로그램 이 반드시 스 레 드 가 안전 한 것 은 아니다.예 를 들 어 스 레 드 1 과 스 레 드 2 는 각각 자신의 데이터 베 이 스 를 만 들 었 고 1 과 데이터 베 이 스 를 연결 했다. 모든 스 레 드 는 자신의 데이터 베 이 스 를 사용 하여 연결 하 는 것 자체 가 스 레 드 가 안전 하 다.그러나 데이터베이스 연결 이 자원 을 가리 키 는 사용 이 반드시 라인 이 안전 한 것 은 아니다.예 를 들 어 두 스 레 드 모두 다음 과 같은 코드 를 실 행 했 습 니 다.
    check if record X exists
    if not, insert record X
         X     ,            X 

만약 에 두 개의 스 레 드 가 동시에 실행 되 고 공교롭게도 그들 이 검사 한 것 이 같은 기록 이 라면 두 개의 스 레 드 가 모두 X 기록 에 삽 입 될 위험 이 있다.다음은 가능 한 상황 입 니 다.
    Thread 1 checks if record X exists. Result = no
    Thread 2 checks if record X exists. Result = no
    Thread 1 inserts record X
    Thread 2 inserts record X

이 경우 여러 스 레 드 에서 공 유 된 파일 이나 다른 자원 에서 도 발생 할 수 있 습 니 다.따라서 하나의 스 레 드 에 의 해 제어 되 는 대상 이 자원 자체 인지 통제 되 는 대상 이 자원 의 인용 일 뿐 인지 구분 하 는 것 이 중요 하 다.
Next: 스 레 드 안전 과 불가 변성

좋은 웹페이지 즐겨찾기