gpt4 book ai didi

java - 使用AtomicInteger时进行同步

转载 作者:行者123 更新时间:2023-12-04 13:09:31 24 4
gpt4 key购买 nike

假设我要实现一个非常简单的Bank Account类,并且要注意并发和多线程问题,

即使synchronizedbalance,也使以下方法AtomicInteger是一个好主意吗?

另一方面,如果我们将所有方法都同步了,那么就不再使用AtomicInteger了,对吗?

import java.util.concurrent.atomic.AtomicInteger;


public class Account {
AtomicInteger balance;
public synchronized int checkBalance(){
return this.balance.intValue();
}
public synchronized void deposit(int amount){
balance.getAndAdd(amount);
}
public synchronized boolean enoughFund(int a){
if (balance.intValue() >= a)
return true;
return false;
}
public synchronized boolean transfer_funds(Account acc, int amount){ // dest : acc
if (enoughFund(amount)){
withdraw(amount);
acc.deposit(amount);
return true;
}
return false;
}
public synchronized boolean withdraw(int amount){
if (checkBalance() < amount)
return false;
balance.getAndAdd(-1 * amount);
return true;
}
}

最佳答案

将您的金额声明为AtomicInteger不会阻止线程在方法执行过程中被抢占(如果未同步)。因此,例如,如果您的方法transfer_funds没有以任何方式同步,即使您的金额为AtomicInteger,您也可能会得到意外的结果

public /* synchronized */ boolean transfer_funds(Account acc, int amount){ // dest : acc 
if (enoughFund(amount)){
withdraw(amount); // <- thread can be preempted in the middle of method execution
acc.deposit(amount);
return true;
}
return false;
}

这些问题称为比赛条件。一个可能的示例是,当两个线程尝试从同一帐户转移资金时。当一个线程确定存在 enoughFund来执行信用转帐时,该线程可能会被抢占,同时另一个线程可以从该帐户开始转帐资金。当第一个线程再次开始处理时,它不会再次检查是否有 enoughFunds来执行信用转移(他已经检查过了,但是他的知识可能已经过时了),但是转到下一个执行行。这样,您可能无法获得一致的结果。您可以更改所有帐户开始时的总金额。

Cay Horstmann的Core Java书中对此方面有很好的解释-此处免费提供 chapter about synchronization。它详细描述了您要问的几乎完全相同的问题。

关于java - 使用AtomicInteger时进行同步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17253260/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com