当前位置: 首页 > 面试题库 >

使用AtomicInteger时进行同步

司马高韵
2023-03-14
问题内容

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

synchronized即使balance是以下方法,还是要这样做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书中对此方面有很好的解释-
这是免费提供的有关同步的章节。它详细描述了您要问的几乎完全相同的问题。



 类似资料:
  • java.util.concurrent.atomic.AtomicInteger类提供对底层int值的操作,可以原子方式读取和写入,还包含高级原子操作。 AtomicInteger支持底层int变量的原子操作。 它具有get和set方法,类似于对volatile变量的读写操作。 也就是说,集合与同一变量上的任何后续获取具有先发生关系。 原子compareAndSet方法也具有这些内存一致性功能。

  • 当想要使用java-stream时,由于lambda表达式中使用了有效的final或final变量约束,使用受到限制。我必须使用使用数组及其第一个也是唯一的索引的变通方法,这是在我的问题如何在Java流中增加一个值的第一个注释中建议的。下面是示例: 是的,这是一个糟糕的解决方案,我没有听到什么好的理由隐藏在一个我找不到的问题的评论中(如果你提醒我其中的一些,如果可能的话,我会投两次票)。但是,如果

  • 我必须使用WebClient进行分页API调用,并最终组合所有结果。例如:个人最新1000交易详情。在一次调用中,我将在json响应(List)中获得最大100个对象。这个人最多只能得到1000条记录。 在伪代码java中,它可能看起来像这样 如何在SpringMVC中以反应式方式编写相同的内容而不阻塞? 像这样的东西???我不知道。帮助我

  • 本文向大家介绍讲讲 AtomicInteger 的使用?相关面试题,主要包含被问及讲讲 AtomicInteger 的使用?时的应答技巧和注意事项,需要的朋友参考一下

  • 问题内容: java.util.concurrent.atomic软件包的javadoc表示以下内容: 一个小的类工具包,支持对单个变量进行无锁线程安全编程。 但是我没有在任何AtomicInteger或AtomicBoolean类中看到任何线程安全的(同步或锁定)代码。 因此,这2个是否相同: 1。 2。 更新 :感谢您的回答。使用AtomicInteger时需要挥发吗? 问题答案: 它们将提供

  • 本文向大家介绍在 Ubuntu 中使用 NTP 进行时间同步设置,包括了在 Ubuntu 中使用 NTP 进行时间同步设置的使用技巧和注意事项,需要的朋友参考一下 NTP 是通过网络来同步时间的一种 TCP/IP 协议。通常客户端向服务器请求当前的时间,并根据结果来设置其时钟。 这个描述是挺简单的,实现这一功能却是极为复杂的 - 首先要有多层 NTP 服务器,第一层 NTP 服务器连接原子时钟,第