Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java - running jobs async using ReentrantLock?

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");
    }
}
like image 890
Marcus Leon Avatar asked Feb 21 '11 17:02

Marcus Leon


1 Answers

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();
            }
        }
    });    
}
like image 69
axtavt Avatar answered Oct 15 '22 18:10

axtavt