java - 关于同步的说明

标签 java concurrency synchronization parallel-processing

假设我有一个类有两个方法 calculateBonus(Account a)calculatePenalty(Account a)

假设我将 synchronized 关键字添加到方法中,或者在方法中有一个 synchronized(this) block 。这是否实际上意味着如果一个线程正在计算一个帐户的奖金,则在奖金完成之前,其他线程无法计算另一个帐户的罚金?

处罚和奖金多种多样且复杂,一个帐户可能同时收到两者。它们的计算顺序无关紧要(有一个截止日期,因此一个不会影响另一个的结果)但重要的是我不要试图同时在同一个帐户上计算两者(对于明显的数据出于一致性原因,每个方法内部都有更新的状态和审计跟踪信息)。

什么是设计我的代码以便我可以安全地最大化并行处理的最佳方式?

到目前为止,我已经考虑了这些选项:

1) 将计算奖金和惩罚的代码放在不同的类中,并在方法上使用synchronized 关键字。不喜欢这个想法,因为我想将一些共享的复杂功能放在一起,它们不受 IO 限制并且执行速度很快,因此不会影响性能。

2) 同步传入的Account 参数。如果我理解正确,这意味着我无法计算在另一个线程中执行的另一个帐户的奖金,直到在第一个线程中的第一个帐户上计算奖金。但我可以计算不同线程中不同帐户的罚款 - 只是不是相同帐户。我最喜欢这个,但想确保我理解正确。

3) 为我要同步的每个方法创建一个内部私有(private)锁对象,一个用于奖励,一个用于惩罚。如果正确理解这一点,则意味着一次只能有一个线程计算奖金,但它不会阻止另一个线程同时计算对同一帐户的罚金时间。

现在我明白我必须小心避免死锁,我计划确保任何同步块(synchronized block)内的任何内容都不依赖于对其他同步方法的调用。我还打算确保影响最终值的计算中使用的任何局部变量都在同步块(synchronized block)内。

最佳答案

我认为选项 2 - 或者它的变体 - 是你最好的选择,但我认为你仍然对它有一点误解:

Synchronize on the passed in Account parameter. If I understand this correctly that means that I can not calculate a bonus on another account executing in another thread until the bonus is calculated on the first account in the first thread.

不 - 这意味着:

  • 您将无法计算同一帐户的奖金罚金,因为您的线程正在监控该帐户。
  • 不过,任何线程都可以在不同帐户上计算奖金或罚款,因为那将有不同的监视器。

现在我通常不喜欢锁定任何公开可见的引用(例如 Account 参数),因为这使得锁定的推理变得更加困难。每个 Account 实例通常最好有自己的对象,仅用于锁定,例如

private final Object lock = new Object();

例如 Account 中的方法来锁定它...但是如果您不能将这些方法放在 Account 中,您就无法真正做到这一点。也许这些方法应该Account 中?也许你应该改变责任 - 以便你有 Account.calculateBonus(BonusFormula)Account.calculatePenalty(PenaltyFormula) 或类似的东西?

在不知道更多细节的情况下很难确定,但通常感觉锁应该只被执行同步的对象知道。

关于java - 关于同步的说明,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5249860/

相关文章:

file - Emacs:经常在Emacs和我的IDE编辑器之间切换,如何自动 'synch'文件?

button - Github 桌面窗口同步按钮消失,历史选项卡不工作

java - jQuery js 文件未加载

java - org.hibernate.MappingNotFoundException : resource: com/ypd/a/entity/Employee. hbm.xml 未找到

java - 无法在 super 账本结构中调用链码

java - 使用 boolean 值同步

java - 为什么 if 语句之后的语句在同步方法中没有按预期运行

java - AtomicInteger 在 JUnit 测试中不会增加

java - 阻塞线程 - Java

java - Java中同步两个方法