以下は、人気のある夫の妻の銀行口座の問題の非スレッドセーフな実装です。
(1つのスレッドが最初にアカウントをチェックし、同じスレッドがwithdrawを実行する前に、別のスレッドがwithdraw操作を実行するため、コードが壊れます)。
Demo.javaファイルの実行後にプログラムのログを見ると。「WifeThread」がメインメモリからAtomicInteger量の値を読み取っていないことは明らかです。
また、単純な「volatileint」を使用して同じ例を試しました。しかし、繰り返しになりますが、私は同じ問題に直面しています:-「Wife-Threadはメインメモリから整数の値を読み取っていません。」
概念を理解するのに役立つように、この動作を説明してください。以下のコードを見つけてください:-
AtomicBankAccount.java
package pack;
import java.util.concurrent.atomic.AtomicInteger;
public class AtomicBankAccount {
private AtomicInteger amount ;
public AtomicBankAccount(int amt) {
this.amount = new AtomicInteger(amt) ;
}
// returns
// -1 for insufficient funds
// remaining balance without subtracting from actual amount for sufficient funds
public int check(int amtToWithdraw){
if(amtToWithdraw <= amount.get()){
System.out.println(Thread.currentThread().getName() + " checks amount : " + amount.get() + ". Remaining ammount after withdrawl should be : " + (amount.get() - amtToWithdraw));
return (amount.get() - amtToWithdraw) ;
}else{
return -1 ;
}
}
// returns
// remaining balance after subtracting from actual amount
public int withdraw(int amtToWithdraw){
amount.getAndAdd(-amtToWithdraw) ;
System.out.println(Thread.currentThread().getName() + " withdraws " + amtToWithdraw + ". Remaining : " + amount.get() + " [latest updated value of account in main memory]");
return amount.get() ;
}
public int getAmount(){
return amount.get() ;
}
}
AtomicWithdrawThread.java
package pack;
public class AtomicWithdrawThread extends Thread{
private AtomicBankAccount account ;
public AtomicWithdrawThread(AtomicBankAccount acnt, String name) {
super(name) ;
this.account = acnt ;
}
@Override
public void run() {
int withDrawAmt = 2 ;
int remaining = 0 ;
while(true){
if( (remaining = account.check(withDrawAmt)) != -1 ){
int temp = account.withdraw(withDrawAmt) ;
if(temp != remaining){
System.out.println("[Race condition] " + Thread.currentThread().getName());
System.exit(1) ;
}
}else{
System.out.println("Empty Account....");
System.exit(1) ;
}
}
}
}
Demo.java
package pack;
public class Demo {
public static void main(String[] args) {
AtomicBankAccount bankAccount = new AtomicBankAccount(1000) ;
AtomicWithdrawThread husbandThread = new AtomicWithdrawThread(bankAccount, "husband") ;
AtomicWithdrawThread wifeThread = new AtomicWithdrawThread(bankAccount, "wife") ;
husbandThread.start() ;
wifeThread.start() ;
}
}
よろしくお願いします、
rits