假设我有一个ExecutorService(它可以是一个线程池,因此涉及并发),它可以在不同的时间执行一个任务,可以是周期性的,也可以是对其他条件的响应。要执行的任务如下:java:executors +任务+锁
- 如果此任务已在进行中,则不执行任何操作(并让先前运行的任务完成)。
- 如果此任务尚未进行,请运行算法X,这可能需要很长时间。
我试图想出一种方法来实现这一点。它应该是这样的:
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(获得= tryLock()
和释放= unlock()
)或的AtomicBoolean或东西,但我不知道它。我需要一个ReentrantLock吗? (也许我想要一个非重入锁,以防algorithmX()
导致此任务以递归方式运行!)或者AtomicBoolean是否足够?
编辑:对于非重入锁,这是否合适?
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.
*/
}
}
建议:不要提交一些复杂的代码并要求某人验证它,请自己尝试,如果遇到不理解的行为,请提出具体问题。 – 2011-02-02 17:14:04
谢谢...这不是我要验证代码,而是我有一种情况,我需要在多线程系统中连续运行一个任务,而且我不知道如何在面对并发问题。我提出的代码仅仅是一个例子。如果我应该使用现有的类,我想知道这一点,因为我正在摸索要问什么精确的问题。 – 2011-02-02 17:17:55
我对并发问题的经验是,尽管你可以尝试使用代码来查看是否存在明显的错误,但不能试着去检查它是否成功,因为可能有奇怪的不可能的拐角条件会显示你的程序不正确,并且可能无法按需重现这些情况。 – 2011-02-02 17:22:31