본문 바로가기
C++ 200제/코딩 IT 정보

자바 쓰레드 안전성을 위한 동기화, 캡슐화 (thread safety 방법)

by vicddory 2018. 5. 9.

자바 쓰레드 안전성을 위한 동기화, 캡슐화 (thread safety 방법)


스레드(Thread, 쓰레드) 안전성을 정의하기는 굉장히 까다롭다. 더 정형화할 수는 있겠지만 복잡해서 실용적 참고나 직관적 이해 어디에도 도움이 안 된다. 남는 것은 계속해서 빙빙 도는 대략적인 설명뿐이다.


구글로 검색하면 다음과 같은 수많은 쓰레드 안전성 '정의'가 나온다.


- 여러 프로그램 스레드에서 스레드 간에 원치 않는 상호 작용 없이 호출할 수 있는...

- 호출하는 측에서 다른 작업을 하지 않고도 여러 쓰레드에서 동시에 호출할 수 있는...


이런 정의를 놓고 보면 쓰레드 안전성 개념이 헛갈리는 것도 무리가 아니다. thread safety가 대체 뭔가?


마치 "여러 스레드에서 안전하게 사용될 수 있으면 해당 클래스는 쓰레드 안전하다"라는 식의 말 같다. 이런 문장에 대해 실제 따지고 들 수는 없지만, 문장 자체가 실질적으로 그리 도움이 되지 않는 것도 사실이다. 스레드 안전하지 않은 클래스와 안전한 클래스는 어떻게 구분할까? 또 '안전하다'는 것은 무슨 뜻일까?


쓰레드에 대한 이해할 만한 정의의 핵심은 모두 정확성correctness 개념과 관계있다. 스레드 안전성에 대한 정의가 모호한 것은 정확성에 대한 명확한 정의가 없기 때문이다. 정확성이란 클래스가 해당 클래스의 명세에 부합한다는 뜻이다.


잘 작성된 클래스 명세는 객체 상태를 제약하는 불변조건invariants과 연산 수행 후 효과를 기술하는 후조건 postcondition을 정의한다.



자바 쓰레드 안전성 안정[Java Thread safety]


하지만 종종 클래스에 대한 명세를 충분히 작성하지 않는 상황에서 과연 작성한 코드가 클래스 명세에 부합하는지 알 수 있을까? thread safety 성립할까?


물론 알 수 없다.


하지만 일단 "특정 코드가 동작한다"고 확신하기만 하면 어쨌든 명세를 활용하지 못할 것도 없다.


이런 '코드 신뢰도code confidence'는 많은 사람이 생각하는 정확성과 대략 일치한다. 이런 맥락에서 단일 스레드에서의 정확성은 '척 보면 아는' 어떤 것이라고 가정하자. 낙관적으로 '정확성'을 인지할 수 있는 어떤 것으로 정의하면 쓰레드 안전성도 다소 덜 순환적으로 정의할 수 있다.


즉 여러 스레드가 클래스에 접근할 때 계속 정확하게 동작하면 해당 클래스는 스레드 안전하다.


여러 스레드가 클래스에 접근한다.

실행 환경이 해당 쓰레드들의 실행을 어떻게 스케줄하든 어디에 끼워 넣든, 호출하는 쪽에서 추가적인 동기화나 다른 조율 없이도 정확하게 동작하면 해당 클래스는 스레드 안전하다고 말한다.


모든 단일 스레드 프로그램은 멀티스레드 프로그램의 한 종류라고 볼 수 있다.



자바 스레드 안정 thread safe[Java Thread safety] 자바 쓰레드 안전성


애당초 단일 스레드 환경에서도 제대로 동작하지 않으면 스레드 안전할 수 없다('정확성'을 너무 느슨한 의미로 사용하는 것 같아 마음이 편치 않다면, 쓰레드 안전한 클래스를 단일 스레드 환경에서보다 더 잘못되지는 않는 클래스라고 정의하는 편이 나을지도 모르겠다).


객체가 제대로 구현됐으면 어떤 일련의 작업(public 메소드를 호출하거나 public 필드를 읽고 쓰는 등의 작업)도 해당 객체의 불변조건이나 후조건에 어긋날 수 없다.


쓰레드에 안전한 클래스 인스턴스에 대해서는 순차적이든 동시든 어떤 작업을 행해도 해당 인스턴스를 잘못된 상태로 만들 수 없다.


스레드 안전한 클래스는 클라이언트 쪽에서 별도로 동기화할 필요가 없도록 동기화 기능도 캡슐화한다.


출처 - 자바 병렬 프로그래밍, 에이콘출판사

자바 쓰레드 안전성을 위한 동기화, 캡슐화 (thread safety 방법)

댓글