Предположим, у меня есть ExecutorService (который может быть пулом потоков, поэтому здесь задействован параллелизм), который выполняет задачу в разное время, либо периодически, либо в ответ на какое-либо другое условие. Задача, которая должна быть выполнена, следующая:
Я пытаюсь придумать способ реализовать это. Это должно быть примерно так:
Runnable task = new Runnable() {
final SomeObj inProgress = new SomeObj();
@Override public void run() {
if (inProgress.acquire())
{
try
{
algorithmX();
}
finally
{
inProgress.release();
}
}
}
}
// re-use this task object whenever scheduling the task with the executor
где SomeObj
либо ReentrantLock (Acquire = tryLock ()
и release = unlock ()
]) или AtomicBoolean или что-то в этом роде, но я не уверен, какой именно. Нужен ли мне здесь ReentrantLock? (Может быть, мне нужна блокировка без повторного входа в случае, если algorithmX ()
заставляет эту задачу запускаться рекурсивно!) Или будет достаточно AtomicBoolean?
edit: для блокировки без повторного входа, это уместно?
Runnable task = new Runnable() {
boolean inProgress = false;
final private Object lock = new Object();
/** try to acquire lock: set inProgress to true,
* return whether it was previously false
*/
private boolean acquire() {
synchronized(this.lock)
{
boolean result = !this.inProgress;
this.inProgress = true;
return result;
}
}
/** release lock */
private void release() {
synchronized(this.lock)
{
this.inProgress = false;
}
}
@Override public void run() {
if (acquire())
{
// nobody else is running! let's do algorithmX()
try
{
algorithmX();
}
finally
{
release();
}
}
/* otherwise, we are already in the process of
* running algorithmX(), in this thread or in another,
* so don't do anything, just return control to the caller.
*/
}
}