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: 182
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