Replies: 1 comment
-
|
객체를 Thread Safe하게 설계한다는 것은 여러 스레드가 동시에 같은 객체를 사용해도 객체의 상태나 불변식이 깨지지 않는 것을 의미하는데요, 그렇기 때문에 우선 설계 측면에서 방어하고 피할 수 없다면(즉, 상태를 갖고 상태가 수정된다면) 스레드들이 객체에 접근하는 매커니즘을 제어하는 방향(예를 들어, 락을 거는 방식)으로 우선순위를 결정할 것 같습니다. 첫번째 고려 사항: 무상태 객체로 우선 작성할 수 있는지 고려하기애초에 변경 가능한 상태가 객체 내에 없다면 해당 객체는 스레드 세이프합니다. 그렇기에 작성하려는 객체가 우선 무상태이라면 Thread safe합니다. 두번째 고려사항: 상태가 있다면 최대한 불변 객체로 만든다.객체가 한번 생성된 이후에는 수정되지 않도록 불변 객체로 설계하는 것으로 Thread-safe를 보장할 수 있습니다. 내부 프로퍼티(상태)를 final 키워드를 사용하여 불변 타입으로 지정하고, 이후 상태 수정과 같은 커멘드 요청이 들어온다면 새로운 객체를 반환하는 형태로 스레드 세이프를 보장할 수 있습니다. 세번째 고려사항: 공유 상태를 수정해야 한다면 일단 락을 걸어 제어한다.앞선 사항을 준수하지 못하고 여러 스레드가 공유하는 상태를 사용할 수 밖에 없을 때는 synchronized와 같은 어플리케이션 락을 걸어 상태에 대한 동시 접근을 방어할 수 있습니다. 혹은 공유 상태의 경우에는 스레드 세이프한 컬렉션을 사용할 수 있습니다. 일반적인 ArrayList와 HashMap은 동시성 충돌에 취약하기 때문에, ConcurrentHashMap와 같은 컬렉션을 이용하여 스레드 세이프를 보장할 수 있습니다. 여기서 중요한 점은, 이런 상태를 보장하는 컬렉션이 스레드 세이프하다고 해도, 전체 로직이 자동으로 스레드 세이프해지는 것은 아닌데요, 즉 해당 컬렉션에 쓰기 작업을 할때 그 컬렉션에만 락이 걸리는 것이지 트랜잭션 내부의 단위 작업들까지도 보장이 되는 것은 아닙니다. (이번 디스커션의 답변은 단일 객체의 동시성 충돌, 스레드 동시 접근에 대해서만 다뤘습니다. 즉, DB와 같은 외부 데이터의 동시접근이 아닌 단일 어플리케이션 내부의 메모리 위 객체의 동시성 충돌 방지까지만 고려하였습니다.) |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
멀티스레드 환경에서 객체를 안전하게 사용하기 위해서는 Thread-safe한 설계가 필요합니다.
자바에서 객체를 Thread-safe하게 만드는 대표적인 방법에는 어떤 것들이 있고, 각 방법은 어떤 상황에서 사용하는 것이 적절할까요?
Beta Was this translation helpful? Give feedback.
All reactions