How to avoid concurrent execution of a time-consuming task without blocking?

Posted by Diego V on Stack Overflow See other posts from Stack Overflow or by Diego V
Published on 2014-06-03T03:02:36Z Indexed on 2014/06/03 3:25 UTC
Read the original article Hit count: 156

Filed under:
|
|

I want to efficiently avoid concurrent execution of a time-consuming task in a heavily multi-threaded environment without making threads wait for a lock when another thread is already running the task. Instead, in that scenario, I want them to gracefully fail (i.e. skip its attempt to execute the task) as fast as possible.

To illustrate the idea considerer this unsafe (has race condition!) code:

private static boolean running = false;

public void launchExpensiveTask() {
    if (running) return; // Do nothing

    running = true;
    try {
        runExpensiveTask();
    } finally {
        running = false;
    }
}

I though about using a variation of Double-Checked Locking (consider that running is a primitive 32-bit field, hence atomic, it could work fine even for Java below 5 without the need of volatile). It could look like this:

private static boolean running = false;

public void launchExpensiveTask() {
    if (running) return; // Do nothing

    synchronized (ThisClass.class) {
        if (running) return;

        running = true;
        try {
            runExpensiveTask();
        } finally {
            running = false;
        }
    }
}

Maybe I should also use a local copy of the field as well (not sure now, please tell me).

But then I realized that anyway I will end with an inner synchronization block, that still could hold a thread with the right timing at monitor entrance until the original executor leaves the critical section (I know the odds usually are minimal but in this case we are thinking in several threads competing for this long-running resource).

So, could you think in a better approach?

© Stack Overflow or respective owner

Related posts about java

Related posts about concurrency