Search code examples
javaasynchronousreentrantlock

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");
    }
}

Solution

  • 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();
                }
            }
        });    
    }