JavaBookStudy / JavaBook

책읽기 스터디
https://javabookstudy.github.io/
Apache License 2.0
19 stars 2 forks source link

[Effective Java] Item 76. 컴퓨터 공학에서의 atomic의 의미 #40

Closed daebalprime closed 3 years ago

daebalprime commented 3 years ago

크게 어려운 내용을 담고있는 것도 아니고 그래서 이슈에 질문할 만큼 궁금한게 없어서 공부하다가 궁금했던 것들 위주로 정리해서 올려 보겠습니다.

우선 일반적으로 CS에서 쓰이는 atomic의 의미부터 먼저 살펴보면, 다른 쓰레드의 입장에서 보았을 때 즉각적으로 끝나는 연산을 atomic이라고 합니다. 이펙티브 자바에서 다루었던 thread safe와는 비슷하지만 느낌이 다른데, 일반적으로 thread safe를 달성하기 위해서 lock, 혹은 운영체제의 semaphore와 같은 배타적인 접근권한을 보장하기 위한 개념을 구현해야 했던 것에 반해서, 어떠한 연산 그 자체가 다른 쓰레드에 의해 불완전한 중간 상태를 노출 시킬 가능성이 없는 것을 atomic이라 이릅니다. 스택 오버플로우에 있는 예제 중 하나는 32비트 프로세서가 64비트 변수를 처리하는 방법에서 생기는 atomic 하지 않은 예시를 다음과 같이 들고 있습니다.

foo = 65465498L; //c언어 코드입니다.

32비트 프로세서에서는 64비트 변수를 native하게 지원하지 않기 때문에, 32비트씩 쪼개어 각각 해당 주소에 저장하는 방식으로 어셈블리가 구현되어 있습니다.

문제는 멀티쓰레드 환경에서 다른 쓰레드가 해당 64비트 변수를 쓰는 도중에 접근할 경우, 해당 변수의 절반인 32비트만 덮어쓰여진 'Intermediate state'를 볼 수 있기 때문에, 다른 쓰레드의 입장에서는 해당 연산이 완료되는 중간을 볼 수가 있기 때문에 atomic하다고 하지 않습니다.

atomic은 원자라는 뜻입니다. 현대 물리학에서 원자는 물질을 이루는 가장 작은 단위가 아님이 이미 알려졌지만, 일반적인 회화 등에선 '쪼갤 수 없음'을 의미하기도 합니다.

TMI) 이러한 일이 벌어지는 이유는 현대 컴파일러에서 코드를 최적화하는 과정(특히 멀티 쓰레드)에서 기계어 실행 순서를 바꾸거나 같은 behavior를 수행하지만 더 효율적인 어셈블리로 바꾸기 때문에 생기는 문제이며, 이러한 atomic함을 보장하기 위해서 해당 변수는 최적화에서 제외하여 해당 변수에 접근할 때, Intermediate 상태를 노출할 수 있는 CPU레지스터에 있는 값 대신 메모리에 직접 접근하여 atomic함을 보장하기 위해 C에서는 volatile이라는 키워드를 사용합니다.

이제 이펙티브 자바의 failure atomic을 살펴보면 객체가 어떤 메서드를 수행하는 도중 실패하더라도 해당 객체에는 영향을 미치지 않는 것을 일컫는데, 예외 발생 시 남은 코드는 실행이 중지되기 때문에 해당 객체는 되다만 상태로 망가지게 됩니다. 다른 쓰레드가 기대하고 또 우리가 신경써야 할 것은, 해당 메서드를 수행하기 전에는 다른 코드에 의해 사용되지 않아야 할 텐데, 앞에서 본 예시와 유사하게 'atomic'하지 않은 실패 상황이기 때문에 망가진 중간상태의 객체가 다른 코드에 의해 사용된다면 재앙적인 상황에 직면하게 될 것입니다.

구미 오는 버스 안에서 작성한 이슈인데 머리 흔들리면서 적으니 글도 흔들흔들하는 느낌이 있네요 궁금하신 점 있으시면 댓글 달아주시거나 스터디 시간에 질문주시면 답변 드리겠습니다.

reference https://dojang.io/mod/page/view.php?id=749 https://docs.oracle.com/javase/tutorial/essential/concurrency/atomic.html https://stackoverflow.com/questions/15054086/what-does-atomic-mean-in-programming/15054186 https://spin.atomicobject.com/2016/01/06/defining-atomic-object/

taxol1203 commented 3 years ago

말씀하신 원자성 atomic은 불완전한 중간 상태를 노출 시킬 가능성이 없는 것이라고 말씀하셨는데,
그럼 failure atomic을 보장하는 객체는 예외 발생시 망가진 중간상태의 객체로 되지 않고, 메서드 호출 이전과 동일하게 롤백한다? 라고 생각하면 될까요?

daebalprime commented 3 years ago

@taxol1203 이해하신 것과는 뉘앙스가 조금 다르긴 합니다만 메서드도 하나의 operation이라고 본다면 중간에 메서드 오퍼레이션이 실패해서 망가진 객체의 상태는,노출하지 말아야 할 intermediate state에 해당합니다. 어떤 오퍼레이션을 완수하지 못한 intermediate state의 객체를 노출하지 않으면 atomic하다고 볼 수 있고, failure에서도 atomic 함을 지키고자 롤백이나 argument validation을 선택하는 것이라 보는 것이 타당합니다. 롤백이 atomic을 보장하는 유일한 수단은 아니기 때문에 롤백하는 것만이 failure atomic을 보장하는 유일한 수단은 아닙니다.