首页 文章

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

提问于
浏览
0

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

class A{
    @Scheduled
    methodX(){
    }
}

class B{
    methodY(){}
}

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

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

因为我必须在两个不同的类中同步两个不同的方法,所以synchronized关键字或块不是正确的解决方案 .

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

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

            sharedSemaphore.release();
        }
    }
}

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

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

2 回答

  • 0

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

    • methodX由调度程序触发,然后更新表中的某些状态 .

    • 方法Y由REST API或其他调度程序触发,然后它首先检查状态并相应地处理 .

  • 0

    如果您可以从MethodX和MethodY中提取公共代码,那么您可以简单地使用synchronized来逃避 .

    虽然,通常这对于Web服务器和rest api来说不是一个好的解决方案,因为很可能你会跨服务器进行水平扩展或负载 balancer .

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

相关问题