【问题标题】:Correct way to use Java Synchronized? [closed]使用 Java Synchronized 的正确方法? [关闭]
【发布时间】:2011-01-31 20:43:35
【问题描述】:

我正在构建一个库存系统,该系统将在具有多个用户的办公室 LAN 上使用。我有一个关于使用同步关键字正确更新库存的查询。我想做的是允许多个用户更新库存,但当然只允许一个用户一次更新。我创建了一个更新库存的方法如下:

public static synchronized boolean UpdateXYZStock(Stock so){
 //update code
}

这是正确的做法吗?

谢谢

S。

【问题讨论】:

  • 您需要在此处提供更多详细信息。
  • java 同步不跨越虚拟机。您可能会考虑让您的数据库处理这样的同步问题。让 UpdateStock() 更新数据库中的股票值。

标签: java synchronization synchronized


【解决方案1】:

我会锁定对象的一个​​实例,而不是类。即不要锁定静态方法,因为您要锁定类。除此之外,您可能希望锁定底层对象,例如

private final Object writeLock = new Object();

public boolean UpdateXYZStock(Stock so) {
   synchronized(writeLock) {
      ...
   }
}

因此您可以更精细地控制锁定的粒度(我假设此方法位于服务器内的组件上,从而为多个客户端提供服务)

【讨论】:

  • 如果我锁定一个底层对象,这是否保证更新代码只执行一次,即如果有多个用户,他们不能同时更新,他们必须依次等待更新库存?
  • 没错。另请注意,如果可以,您应该在数据库中使用事务和保证原子性。
  • 太棒了,非常感谢布赖恩!
【解决方案2】:

在静态方法上同步的唯一问题是您实际上是在整个类上同步。因此,如果您在该类中有多个静态方法,则该类已同步这一事实将阻止其他类访问任何静态方法,直到该类完成。

否则应该完成你想要的。

【讨论】:

  • 我在课堂上确实有其他静态方法,所以我认为Brian的建议会更合适
【解决方案3】:

您也可以考虑使用ReadWriteLock

【讨论】:

    【解决方案4】:

    以这种方式使用synchronized 很好。这取决于您实际存储数据的位置。如果它只是存储在一个对象中,请使用该对象的监视器,即非静态同步方法。

    如果您将数据存储在数据库中,请确保更新表中该行的所有代码都使用相同的锁。正如其他回复中突出显示的那样,这可以是您通过静态字段提供的对象。 (只是不要使用字符串作为监视器)。

    【讨论】:

    • 代码存储在数据库中
    • 你在为数据库使用乐观还是悲观的锁定协议?
    • 我猜在这种情况下,你根本不需要同步。持久层会判断您是否在更新陈旧数据。
    猜你喜欢
    • 2012-05-17
    • 1970-01-01
    • 2016-09-02
    • 2013-06-27
    • 1970-01-01
    • 2015-04-23
    • 1970-01-01
    • 2012-12-20
    • 1970-01-01
    相关资源
    最近更新 更多