두 개의 잠금 인 inventoryLock 및 currencyLock을 가진 객체 User가 있습니다. 종종 이러한 잠금은 개별적으로 사용됩니다 (예 : 쉽게 교착 상태를 피하는 방법은 무엇입니까?
synchronized (user.currencyLock) {
if (user.money < loss) throw new Exception();
user.money -= loss;
}
그러나
synchronized (user.inventoryLock) {
// swap items
tmp = user.inventory[x];
user.inventory[x] = user.inventory[y];
user.inventory[y] = tmp;
}
또는
때때로 코드 조각이 모두 잠금 장치가 필요합니다synchronized (user.currencyLock) {
synchronized (user.inventoryLock) {
if (user.money < item.price) throw new Exception();
user.money -= item.price;
user.inventory[empty] = item;
}
}
간단한 보인다, 그러나 단지이 예보다 모두 잠금 장치를 사용하여 코드의 더 많은 비트가, 이전 경험에서 알 수 있듯이 여러 개의 코드에 동일한 공유 잠금이 필요한 경우 교착 상태가 발생할 위험이 있습니다.
이를 피하는 좋은 방법은 무엇입니까?
두 개체에 원자 적으로 잠글 수있는 메커니즘이 있습니까?
코드에 심각한 캡슐화가 없음을 보여줍니다. 방법을 거치지 않고 사용자의 상태에 직접 액세스합니다. 상태를 클래스에 캡슐화하여 동기화를 중앙 집중화하고 필요한 모든 동기화가 완료되었는지 확인해야합니다. User 클래스 자체에서이 서비스를 제공하는 대신 사용자의 모든 클라이언트가 올바르게 동기화되도록해야합니다. –
@JBNizet 이것은 예제 코드 일뿐입니다. 실제 코드는 사용자 클래스가 수행 할 수없는 데이터베이스 호출을 포함합니다. –