简体   繁体   English

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

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

I have a usecase, where I have to prevent two different methods in two different classes to run at the same time ie If Class A has method X and Class B has method Y, I have to make sure that when methodX is being executed, I should not allow method Y to execute or block the execution until methodX is completed. 我有一个用例,必须防止两个不同的类中的两个不同的方法同时运行,即如果类A具有方法X,类B具有方法Y,则必须确保在执行methodX时,我在methodX完成之前,不应允许方法Y执行或阻止执行。

class A{
    @Scheduled
    methodX(){
    }
}

class B{
    methodY(){}
}

A bit of background, Here methodX is a scheduled process which is responsible for reading data from a remote database, transform, do some mappings and store it in the local database. 有点背景,这里methodX是一个调度过程,负责从远程数据库读取数据,进行转换,执行一些映射并将其存储在本地数据库中。

methodY is a generic implementation (can be triggered by a REST call or another scheduled process) which reads data from different sources, one of the source is the data which is stored by methodX , after reading it also does some mappings and sends the data to another system. methodY是一种通用实现(可以由REST调用或另一个调度的进程触发),它从不同的源读取数据,其中一个源是methodX存储的数据,在读取后它还会进行一些映射并将数据发送到另一个系统。

As I have to synchronize two different methods inside two different classes the synchronized keyword or block is not the right solution. 由于我必须在两个不同的类中同步两个不同的方法,因此synced关键字或block不是正确的解决方案。

I used a shared counting semaphore here in method X and method Y, ie 我在方法X和方法Y中使用了共享的计数信号量,即

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

            sharedSemaphore.release();
        }
    }
}

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

The above code sample is just a small part of the actual implementation, is there any better way to do this ? 上面的代码示例只是实际实现的一小部分,有没有更好的方法呢? Is semaphore a right concurrency primitive to use here ?How to make sure two different methods in two different classes do not execute at the same time ? 信号量是在此处使用的正确的并发原语吗?如何确保两个不同类中的两个不同方法不会同时执行?

If it is happening from two different flow then why cant you store some state in DB ? 如果是从两个不同的流中发生的,那为什么不能在DB中存储一些状态呢? eg 例如

  1. methodX is triggered by scheduler then it updates some state in table. methodX由调度程序触发,然后更新表中的某些状态。
  2. methodY is triggered by REST API or another scheduler then it first checks the state and process accordingly. methodY由REST API或其他调度程序触发,然后首先检查状态并进行相应处理。

If you can extract a common code from MethodX and MethodY then you can simply get away with synchronised. 如果您可以从MethodX和MethodY中提取通用代码,那么您就可以轻松地实现同步。

Although, generally this is not a good solution for web server and rest api as most probably you will horizontal scale or load balance across servers. 虽然,通常,这对于Web服务器和rest api而言不是一个好的解决方案,因为您很可能会在服务器之间进行水平扩展或负载平衡。

So it comes down to serializing code( by locking?) across machines. 因此,可以归结为跨机器序列化代码(通过锁定?)。 Not sure what is your tech stack is but options can be use locking based on database ,mysql get_lock or oracle dbms_lock,some database state(this is almost you are rolling your own locking mechanism), or task queue, if you are using some messaging frame. 不确定您的技术堆栈是什么,但是可以使用基于数据库的锁定,mysql get_lock或oracle dbms_lock,一些数据库状态(这几乎是您正在使用自己的锁定机制)或任务队列(如果使用的是消息传递)帧。 Also you can use akka actors. 您也可以使用Akka演员。

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

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