我有一个方法,比如说method1(),需要一段时间才能运行。在执行期间,如果再次调用method1(),则应该忽略它。我大致有类似的东西
boolean mFlag = false;
void method1()
{
if(!mFlag)
{
mFlag=true;
// do Stuff
mFlag=false;
}
}
这很有效。但我想知道是否有更好的方法来做到这一点,最好不要涉及任何旗帜。
答案 0 :(得分:6)
是的,您应该使用java.util.concurrent.locks中的内容。您的示例不是非常严格,布尔值必须是易变的。
ReentrantLock lock = new ReentrantLock();
void method1()
{
if(lock.tryLock())
{
try {
if (!(lock.getHoldCount() > 1)) {
//do Some Stuff
}
} finally {
lock.unlock();
}
}
}
编辑处理在重新录入时跳过执行,如评论中所述。不幸的是,使用内置库并没有很好的方法,因为它有点奇怪的用法,但我仍然认为使用内置库是一个更好的选择。
答案 1 :(得分:1)
您是否正在尝试防止同一线程重新进入或同时访问多个线程。
假设多线程访问,轻量级方法是使用java.util.concurrent.atomic
。不需要像锁一样“重”的东西(只要没有进一步的要求)。
假设不使用同一方法重新进入:
private final AtomicBoolean inMethod = new AtomicBoolean();
void method1() {
if (inMethod.compareAndSet(true, false)) { // Alternatively getAndSet
try {
// do Stuff
} finally {
inMethod.set(false); // Need to cover exception case!
}
}
}
如果你想在同一个线程中允许重新进入,那么使用锁就足够了:
private final AtomicReference<Thread> inMethod = new AtomicReference<Thread>();
void method1() {
final Thread current = Thread.currentThread();
final Thread old = inMethod.get();
if (
old == current || // We already have it.
inMethod.compareAndSet(null, current) // Acquired it.
) {
try {
// do Stuff
} finally {
inMethod.set(old); // Could optimise for no change.
}
}
}
可以使用Execute Around成语。
答案 2 :(得分:0)