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
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.