简体   繁体   中英

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.

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.

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.

As I have to synchronize two different methods inside two different classes the synchronized keyword or block is not the right solution.

I used a shared counting semaphore here in method X and method Y, ie

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 ? eg

  1. methodX is triggered by scheduler then it updates some state in table.
  2. methodY is triggered by REST API or another scheduler then it first checks the state and process accordingly.

If you can extract a common code from MethodX and MethodY then you can simply get away with synchronised.

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.

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. Also you can use akka actors.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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