0

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

class A{
    @Scheduled
    methodX(){
    }
}

class B{
    methodY(){}
}

一点背景知识,这methodX是一个计划进程,负责从远程数据库读取数据、转换、做一些映射并将其存储在本地数据库中。

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

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

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

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

            sharedSemaphore.release();
        }
    }
}

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

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

4

2 回答 2

0

如果您可以从 MethodX 和 MethodY 中提取公共代码,那么您可以简单地摆脱同步。

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

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

于 2018-12-10T08:46:14.327 回答
0

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

  1. methodX 由调度程序触发,然后它更新表中的某些状态。
  2. methodY 由 REST API 或其他调度程序触发,然后它首先检查状态并相应地处理。
于 2018-12-10T01:44:14.020 回答