繁体   English   中英

并发性:如何防止两个不同类中的两个方法同时运行?

[英]Concurrency: How to prevent two methods in two different classes to run at the same time?

我有一个用例,必须防止两个不同的类中的两个不同的方法同时运行,即如果类A具有方法X,类B具有方法Y,则必须确保在执行methodX时,我在methodX完成之前,不应允许方法Y执行或阻止执行。

class A{
    @Scheduled
    methodX(){
    }
}

class B{
    methodY(){}
}

有点背景,这里methodX是一个调度过程,负责从远程数据库读取数据,进行转换,执行一些映射并将其存储在本地数据库中。

methodY是一种通用实现(可以由REST调用或另一个调度的进程触发),它从不同的源读取数据,其中一个源是methodX存储的数据,在读取后它还会进行一些映射并将数据发送到另一个系统。

由于我必须在两个不同的类中同步两个不同的方法,因此synced关键字或block不是正确的解决方案。

我在方法X和方法Y中使用了共享的计数信号量,即

class A{
    @Scheduled
    methodX(){
        if(sharedSemaphore.tryAcquire()){       
            // read data, do mappings etc.
            ...
            ...

            sharedSemaphore.release();
        }
    }
}

class B{
    methodY(){
     if(sharedSemaphore.tryAcquire()){
         ...
         ...
         ...
         sharedSemaphore.release();
     }
    }
}

上面的代码示例只是实际实现的一小部分,有没有更好的方法呢? 信号量是在此处使用的正确的并发原语吗?如何确保两个不同类中的两个不同方法不会同时执行?

如果是从两个不同的流中发生的,那为什么不能在DB中存储一些状态呢? 例如

  1. methodX由调度程序触发,然后更新表中的某些状态。
  2. methodY由REST API或其他调度程序触发,然后首先检查状态并进行相应处理。

如果您可以从MethodX和MethodY中提取通用代码,那么您就可以轻松地实现同步。

虽然,通常,这对于Web服务器和rest api而言不是一个好的解决方案,因为您很可能会在服务器之间进行水平扩展或负载平衡。

因此,可以归结为跨机器序列化代码(通过锁定?)。 不确定您的技术堆栈是什么,但是可以使用基于数据库的锁定,mysql get_lock或oracle dbms_lock,一些数据库状态(这几乎是您正在使用自己的锁定机制)或任务队列(如果使用的是消息传递)帧。 您也可以使用Akka演员。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM