The code below allows us to run a job
while ensuring that only one job at a time can run by using ReentrantLock
.
Is there any way to modify this code to run job.call()
asynchronously and to return the MyConcurrentJobException
to the client prior to starting the thread?
We tried wrapping the try/catch/finally block in a new Thread
but the unlock
and lock
have to happen in the same thread so we get an IllegalMonitorException
??
final static Lock lock = new ReentrantLock();
public Object runJob(String desc, Callable job, boolean wait) {
logger.info("Acquiring lock");
if (!lock.tryLock()) {
throw new MyConcurrentJobException();
}
activeJob = new JobStatus(desc);
logger.info("Lock acquired");
try {
return job.call();
} catch (MarginServiceAssertionException e) {
throw e;
} catch (MarginServiceSystemException e) {
throw e;
} catch (Exception e) {
throw new MarginServiceSystemException(e);
} finally {
activeJob = null;
logger.info("Releasing lock");
lock.unlock();
logger.info("Lock released");
}
}
You can use Semaphore
instead of ReentrantLock
, its permits are not bound to thread.
Something like this (not sure what you want to do with the result of job.call()
in the asynchronous case):
final static Semaphore lock = new Semaphore(1);
public void runJob(String desc, Callable job, boolean wait) {
logger.info("Acquiring lock");
if (!lock.tryAcquire()) {
throw new MyConcurrentJobException();
}
startThread(new Runnable() {
public void run() {
try {
job.call();
} finally {
lock.release();
}
}
});
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With