Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/338.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java并发性:我是否必须同步一个只检索状态而不修改状态的方法?_Java_Concurrency_Synchronization - Fatal编程技术网

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

我正在学习java并发,并使用了一个多人共享的银行帐户示例来尝试实践并发原则

这是我的会计课

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)
或在您为此创建的
对象锁上同步。