我有一个用例,其中必须防止两个不同类中的两个不同方法同时运行,即如果A类具有方法X而B类具有方法Y,则必须确保在使用methodX时执行后,在methodX完成之前,我不应该允许方法Y执行或阻止执行。
class A{
@Scheduled
methodX(){
}
}
class B{
methodY(){}
}
有点背景,
methodX
是一个计划好的过程,负责从远程数据库读取数据,进行转换,执行一些映射并将其存储在本地数据库中。
methodY
是一种通用实现(可以由REST调用或另一个计划的进程触发),它从不同的源读取数据,其中一个源是methodX
存储的数据,之后读取它还会进行一些映射,并将数据发送到另一个系统。
由于我必须在两个不同的类中同步两个不同的方法,所以sync关键字或块不是正确的解决方案。
在这里,我在方法X和方法Y中使用了共享计数信号量,即
class A{
@Scheduled
methodX(){
if(sharedSemaphore.tryAcquire()){
// read data, do mappings etc.
...
...
sharedSemaphore.release();
}
}
}
class B{
methodY(){
if(sharedSemaphore.tryAcquire()){
...
...
...
sharedSemaphore.release();
}
}
}
上面的代码示例只是实际实现的一小部分,有没有更好的方法呢?信号量在这里使用正确的并发原语吗?如何确保两个不同类中的两个不同方法不能同时执行?
答案 0 :(得分:0)
如果它是从两个不同的流中发生的,那为什么不能在DB中存储一些状态呢? 例如
答案 1 :(得分:0)
如果您可以从MethodX和MethodY中提取通用代码,则可以轻松进行同步。
尽管,通常,这对于Web服务器和rest api来说不是一个好的解决方案,因为您很可能会在服务器之间横向扩展或平衡负载。
因此可以归结为跨机器序列化代码(通过锁定?)。不确定您的技术堆栈是什么,但是可以使用基于数据库的锁定,mysql get_lock或oracle dbms_lock,一些数据库状态(这几乎是您正在使用自己的锁定机制)或任务队列(如果使用的是消息传递)帧。您也可以使用Akka演员。