Java 同步类实例

标签 java multithreading synchronization

我似乎找不到任何我想问的例子:

假设我在类里面有帐户

public void transferMoney(Account fromAccount, Account toAccount, DollarAmount amountToTransfer) { 
    if (fromAccount.hasSufficientBalance(amountToTransfer) { 
       fromAccount.debit(amountToTransfer); 
       toAccount.credit(amountToTransfer);
    }
}

这在重写的运行方法中使用时可能会导致竞争条件,我在 Main 中有这段代码:

Account acc1 = new Account(..);
Account acc2 = new Account(..);
Thread t1 = new Thread(new Transfer(..from acc1 to acc2..));
Thread t2 = new Thread(new Transfer(..from acc2 to acc1..));
synchronized (acc1) {
    t1.start();
}
synchronized (acc2) {
    t2.start()
}

同步帐户 acc1 和 acc2 的这两个实例不会阻止竞争条件,但我不知道为什么或同步在这种情况下究竟做了什么! 我找不到任何关于这种同步的例子。

最佳答案

synchronized 仅在线程试图进入 synchronized block 而另一个线程当前 处于 synchronized< 时才有效 引用同一对象的 block 。在这里,只有您的主线程在 acc1acc2 上同步,因此实际上不会发生任何同步。

针对您的情况,更好的设计是将 hasSufficientBalancedebit 聚合到一个同步的方法中(相当于将整个方法主体包含在一个 synchronized(this) block )。此 synchronized 用于保护类的内部状态。因此,您还需要将 credit 方法标记为 synchronized

public synchronized boolean debitIfHasSufficientBalance(DollarAmount amount) {
   if (hasSufficientBalance(amount)) {
     debit(amount);
     return true;
   }
   return false;
}

您的 transferMoney 可以重写如下,无需任何显式同步:

public void transferMoney(Account fromAccount, Account toAccount, DollarAmount amountToTransfer) {
  if (fromAccount.debitIfHasSufficientBalance(amountToTransfer)) {
    toAccount.credit(amountToTransfer);
  }
}

关于Java 同步类实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26149736/

相关文章:

java - Vert.x 的 Verticle(s) JSON/YAML 配置(每个环境最好)

node.js - NodeJS - libuv 线程池是全局的还是每个进程的?

java - 如何使用 Swing 暂停 Java 模拟

java - 多线程程序无法运行

c++ - 上下文对象的同步

java - 无法让 JAXB 解析来自 Yahoo! 的 XML金融到 java

java - maven java编译: is there concurrent mode?

audio - 在ffmpeg中同步音频和视频的结尾?

java - 数字金字塔,初学递归追踪难吗?

c++ - 等待变量变化