4

一个简单的例子:

      class Account{
           private String account_name;
           private String password;
           private double balance;

           public synchronized double getBalance(){
                  return balance;
           }
           public synchronized void setBalance(double add){
                  balance += add;
           }
      }

据我了解,获取与对象关联的锁不会阻止其他线程访问该对象。它们必须是相同的锁才能防止访问。

因此,如果两个人尝试在不同的 ATM 上访问同一个帐户,那么它将创建该Account对象的两个不同实例,对吗?那么它不是用同一个锁看守的,对吧?

假设人 A(线程 A)试图将钱存入帐户,而同时人 B(线程 B)试图获得帐户的总余额。

它是如何工作的 ?他们是否缓存了正在使用的时间,以便在下一个请求进来时Account返回相同的对象?Account

4

4 回答 4

5

同步方法将锁定对象实例。但是,如果有一种方法,则可能会发生不同步的并发访问。

ATM 机不会访问您的帐户 - 银行服务器会。ATM机只是一个客户端。因此,从 2 个不同的 ATM 访问同一个帐户将受到银行服务器的保护,该服务器的内存/数据库中只有一个该帐户的实例(可能受到某种锁定机制的保护,而不是用 Java 编写的)。

于 2012-09-02T14:57:45.600 回答
0

据我了解,获取与对象关联的锁不会阻止其他线程访问该对象。它们必须是相同的锁才能防止访问。

正确的。如果多个线程试图获取一个简单的锁,那么只有 on 将被允许继续。不过,锁不一定需要与单个对象关联。您也可以为其他任务创建锁。

因此,如果两个人尝试在不同的 ATM 上访问同一个帐户,那么它将创建此 Account 对象的两个不同实例,对吗?那么它不是用同一个锁看守的,对吧?假设人 A(线程 A)试图将钱存入帐户,而同时人 B(线程 B)试图获得帐户的总余额。它是如何工作的 ?他们是否在使用时缓存帐户,以便在下一个请求进入时返回相同的帐户对象?

有点,你描述的是一个分布式锁定场景,这是完全不同的。正如有人已经提到的,ATM 会将交易发回银行处理,那里的服务器将处理并发问题。

于 2012-09-02T16:24:35.330 回答
0

我最好的猜测是他们正在使用像缓存这样的对象池,当请求到来时,它会通过使用一些唯一标识符(如帐号)来搜索池中存在的特定对象(帐户)。如果存在引用将被返回。否则,它将从持久数据源加载到池中,并将创建并返回新的引用。因此,即使是两个用户(线程)也尝试同时访问它。服务器不会为每个实例创建两个实例。

其次,如果一个类中有多个同步方法,并且如果一个线程当前正在同步方法中执行,则所有其他尝试访问同一对象的任何同步方法的线程都将被阻止(暂停执行),直到第一个线程存在同步方法。

于 2012-09-02T16:02:21.223 回答
0

这取决于系统的实施方式。通常你有一个类的实例,每个实例都有一个与之关联的隐式锁,或者你可以创建一个简单的

私有对象锁;

然后每个人(无论是 ATM 还是银行员工或其他人)都必须明确获得这个锁。归根结底,它归结为系统是如何设计和实现的——锁定原语就是这样——原语。由设计者/实现者来使用并在每个组件中适当地使用它们 - 一致的锁定。此外,在这种情况下,我会选择原子替身并省去获取潜在重对象锁的麻烦。

于 2012-09-02T14:55:24.180 回答