홈>
교착 상태 예제를 찾고 있었고이 코드를 우연히 발견했습니다 :
package com.example.thread.deadlock._synchronized;
public class BankAccount {
double balance;
int id;
BankAccount(int id, double balance) {
this.id = id;
this.balance = balance;
}
void withdraw(double amount) {
// Wait to simulate io like database access ...
try {Thread.sleep(10l);} catch (InterruptedException e) {}
balance -= amount;
}
void deposit(double amount) {
// Wait to simulate io like database access ...
try {Thread.sleep(10l);} catch (InterruptedException e) {}
balance += amount;
}
static void transfer(BankAccount from, BankAccount to, double amount) {
synchronized(from) {
from.withdraw(amount);
synchronized(to) {
to.deposit(amount);
}
}
}
public static void main(String[] args) {
final BankAccount fooAccount = new BankAccount(1, 100d);
final BankAccount barAccount = new BankAccount(2, 100d);
new Thread() {
public void run() {
BankAccount.transfer(fooAccount, barAccount, 10d);
}
}.start();
new Thread() {
public void run() {
BankAccount.transfer(barAccount, fooAccount, 10d);
}
}.start();
}
}
transfer
를 어떻게 바꾸겠습니까
교착 상태를 유발하지 않도록 방법? 첫 번째 생각은 모든 계정에 대해 공유 잠금을 만드는 것이지만 물론 모든 동시성을 죽일 것입니다. 거래와 관련된 두 개의 계정 만 잠그고 다른 계정에는 영향을 미치지 않는 좋은 방법이 있습니까?
- 답변 # 1
- 답변 # 2
네스트 대신 두 개의 동기화 된 블록을 별도로 사용하십시오.
synchronized(from){ from.withdraw(amount); } synchronized(to){ to.deposit(amount); }
from.withdraw(amount)
이후from
의 잠금이라고합니다.to
를 잠그기 전에 해제됩니다.
관련 자료
- javascript - 동시에 여러 키를 사용하여 객체 배열을 정렬하는 방법은 무엇입니까?
- c# - foreach 루프 전에 관련/구성/집계 된 개체의 계층 구조에 대한 많은 null 검사를 피하는 방법은 무엇입니까?
- java - 여러 개체에 MouseWheel 이벤트를 포착/전달하는 방법은 무엇입니까?
- mongodb - 객체를 포함하는 배열에 여러 필드 추가
- java - JayWay JSONPath를 사용하여 여러 깊이에서 여러 JSON 객체 추출
- vb.net - 반복하여 여러 객체를 만든 다음 winform에서 각 객체에 세 개의 텍스트 상자 값을 할당하십시오
- r - 'orderby'의 색인 항목이 고유하지 않은 경우"zoo"개체에 대한 일부 방법이 작동하지 않는 것을 어떻게 피할 수 있습니까?
- joi 유효성 검사에서 두 객체 비교 (예 - 중복 방지)
관련 질문
- JAVA에서 실행기 서비스와 병렬로 동일한 기능을 호출하는 방법은 무엇입니까?
- java : 목록을 사용하여 병렬로 함수를 호출하는 방법은 무엇입니까?
- java : blockingQueue에서 JList를 표시하는 방법은 무엇입니까?
- java : 메인 스레드와 종료
- java : 지속적으로 출력을 인쇄하도록 내 JFrame 버튼을 만들 수 있습니까?
- java : threadPool과 비교하여 Vert.x의 장점은 무엇입니까?
- c# : 스레드로부터 안전한 WebApi 넣기 요청
- Java 실행기 프레임워크에서 ThreadFactory로 ThreadPoolExecutor 이해하기
- C# async/await와 Java의 CompletableFuture 간에 비동기 프로그래밍에 차이점/제한이 있습니까?
- java : 멀티스레딩에서 폴링 줄이기
멀티 록 상황에서 교착 상태를 피하는 한 가지 방법은 항상 같은 순서로 개체를 잠그는 것입니다.
이 경우 모든
이것은BankAccount
에 대해 총 주문을 생성한다는 의미입니다. 사물. 운 좋게도 사용할 수있는 ID가 있으므로 항상 하위 ID를 먼저 잠근 다음 다른 동기화 된 블록 내에서 상위 ID를 잠글 수 있습니다.BankAccount
가 없다고 가정합니다. 동일한 ID를 가진 객체이지만 합리적인 가정처럼 보입니다.