Java并发性:我是否必须同步一个只检索状态而不修改状态的方法?
我正在学习java并发,并使用了一个多人共享的银行帐户示例来尝试实践并发原则 这是我的会计课Java并发性:我是否必须同步一个只检索状态而不修改状态的方法?,java,concurrency,synchronization,Java,Concurrency,Synchronization,我正在学习java并发,并使用了一个多人共享的银行帐户示例来尝试实践并发原则 这是我的会计课 public class Account(){ private int balance = 0; public int getBalance(){ return balance} public synchronized void deposit(int val){//..} void synchronized void withdraw
public class Account(){
private int balance = 0;
public int getBalance(){ return balance}
public synchronized void deposit(int val){//..}
void synchronized void withdrawal(int val){//..}
}
存款和取款方法是同步的,因为它们直接修改Account对象的状态,从而避免在多个用户同时尝试更改时数据损坏
另一方面,
getBalance()
不会更改Account对象的状态。但是我想如果在存款或取款时调用getBalance()
,它将返回一个过时的值。同步或不同步的标准做法是什么 IMHO,当您试图修改属性时,需要同步以避免“竞争条件”。
因此,如果你修改它,你可以预测结果。否则,您无法保证输出是什么
除此之外,我可能会将balance属性包装到某个AtomicInteger中,或者至少将其标记为volatile。您需要同步一个对象,而不是文字,因为只同步对性能比函数更重要的对象
Object lock = new Object();
public class Account(){
private int balance = 0;
public int getBalance(){ synchronized (lock){return balance} }
public void deposit(int val){synchronized (lock){...} }
void withdrawal(int val){synchronized (lock){...} }
}
}
通过这种方式,您可以在函数中添加更多逻辑,以便在更新时更好地执行并保持平衡同步
如果在存款或取款时调用getBalance(),它将返回过期的值
当这些进程运行时,没有过时的值,只是因为您无法确定它们是否会失败(我假设您没有使用中间状态表示的balance
字段)
所以,问题实际上是——你想阅读最近的余额状态,不管取款或存款是否在运行,都要这样做吗?或者,您希望等待其中一个进程完成,以便读取值
在第一种情况下,您可以简单地将字段设置为volatile(private volatile int balance=0;
),以确保线程之间的内存可见性。在第二种情况下,只需使用
synchronized
就可以了,但不确定您希望在这里得到什么样的答案。。。如果要确保获得最新值,请使用synchronized
,如果不介意,请不要使用synchronized
。不要使用Integer
而不是int
在对象上进行同步。synchronize(this)
或在您为此创建的对象锁上同步。