【问题标题】:How to synchronize block in method如何在方法中同步块
【发布时间】:2023-03-04 11:54:01
【问题描述】:

我正在构建一个会计应用程序,并且已经编写了一种方法来将发票保存到数据库 (MongoDB) 中。在保存发票之前,我必须创建一个数字(字母数字字符),以增加上次保存的发票编号。基本上,我必须阅读最后创建的发票以获取号码并重复使用该号码 + 1 来保存新发票。为了保持发票编号一致,我写了如下方法:

public synchronized void saveInvoice(InvoiceObject object){
   //Get the last invoice and increment the number
   //Save the InvoiceObject with the incremented number
}

到目前为止一切都很好,但是由于这个应用程序被多个客户端使用,每个客户端都有自己的发票编号序列,因此,我希望在保存发票的同时阻止所有客户端(线程)(因为同步)允许多个客户端“同时”访问该方法并对同一客户端的请求进行排队(以保持适当增加其发票顺序)。

总而言之,这是我想要实现的图表: Diagram

我怎样才能做到这一点?

谢谢:-)

【问题讨论】:

  • 数据库可以使用 AUTO_INCREMENT 自动为您执行此操作。不要为此编写代码。
  • 我认为你没有理解这个问题。
  • @TomazFernandes 如果这是写给我的,那我肯定是写给我的。
  • AUTO_INCREMENT 在这里不起作用,因为 OP 明确指出每个客户都有自己的发票编号
  • @user207421,AUTO_INCREMENT 不能在这里工作,因为发票编号是每个客户的,而不是系统范围的。例如,客户 A 可以有编号,例如 ABC001、ABC002、ABC003...,而客户 B 可以有编号 DEF001、DEF002、DEF003,...客户选择他们的编号前缀和最后 3(或更多)位自动增量。希望这更清楚:-)

标签: java multithreading design-patterns concurrency


【解决方案1】:

通常,您可以通过使用带有您指定的锁的synchronized 块来防止多个线程在方法中执行关键部分。

class InvoiceRepository {

  private final Object lock = new Object();

  private int number;

  public void saveInvoice(InvoiceObject object) {
    int myNumber;
    synchronized(lock) {
      myNumber = ++number;
    }
    /* Save the invoice... */
  }

如果需要,您可以使用 Lock implementation 来获得更多功能,例如可中断性或锁定获取超时,而不是使用带有简单 Object 的内部锁定。

但在这种情况下,AtomicInteger(或AtomicLong)看起来很合适:

class InvoiceRepository {

  private final AtomicInteger number = new AtomicInteger();

  public void saveInvoice(InvoiceObject object) {
    int myNumber = number.incrementAndGet();
    /* Save the invoice. */
  }

【讨论】:

    【解决方案2】:

    您可以根据客户的 id 进行锁定。

    查看此答案以获取有关如何实现它的详细信息: Java synchronizing based on a parameter (named mutex/lock)

    如果您提前知道所有客户 ID,Tudor 的答案会很好,如果不检查 Timmo 的答案,它是动态的、更完整的,虽然更复杂。

    希望对你有帮助!

    【讨论】:

    • 锁定每个客户端并不能实现目标。发票编号必须在系统范围内是唯一的,而不仅仅是每个客户。
    • OP 不是这么说的:“到目前为止还不错,但是由于这个应用程序被多个客户使用,每个客户都有自己的发票编号顺序”
    • @TomazFernandes 谢谢我会试试 Timmo 的回答,因为我需要一个“动态”锁。
    • 终于用上了String.intern()方法
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-27
    • 1970-01-01
    • 2022-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多