在java中有没有其他/更好的方法来实现这个简单的逻辑?
我有一个方法,比如method1(),需要一段时间才能运行。在执行过程中,如果有另一个对method1()的调用,则应该忽略它。大致上,我有这样的想法在java中有没有其他/更好的方法来实现这个简单的逻辑?,java,Java,我有一个方法,比如method1(),需要一段时间才能运行。在执行过程中,如果有另一个对method1()的调用,则应该忽略它。大致上,我有这样的想法 boolean mFlag = false; void method1() { if(!mFlag) { mFlag=true; // do Stuff mFlag=false; } } 这很有效
boolean mFlag = false;
void method1()
{
if(!mFlag)
{
mFlag=true;
// do Stuff
mFlag=false;
}
}
这很有效。但是我想知道是否有更好的方法来做到这一点,最好不涉及任何标志。也许你应该使用同步方法
是的,您确实应该使用java.util.concurrent.locks中的内容。您的示例并不完全正确,布尔值需要是可变的
ReentrantLock lock = new ReentrantLock();
void method1()
{
if(lock.tryLock())
{
try {
if (!(lock.getHoldCount() > 1)) {
//do Some Stuff
}
} finally {
lock.unlock();
}
}
}
编辑以处理注释中指示的重新进入时跳过执行。不幸的是,使用内置库并不是一个很好的方法,因为这是一个有点奇怪的用例,但我仍然认为使用内置库是一个更好的选择。您是否试图防止来自同一线程或多个线程同时访问的重入 假设多线程访问,轻量级方法是使用
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.
}
}
}
private final AtomicReference inMethod=new AtomicReference();
void method1(){
最终螺纹电流=Thread.currentThread();
final Thread old=inMethod.get();
如果(
old==current | |//我们已经有了它。
inMethod.compareAndSet(null,current)//获取了它。
) {
试一试{
//做事
}最后{
inMethod.set(old);//无法对其进行优化而不进行任何更改。
}
}
}
可以使用executearound习惯用法来实现这一点。这很好。通常是这样做的。您是想解决多个线程同时执行同一个方法的问题,还是该方法(可能是间接地)调用自身的问题?@Anon the method interactive calling self.@Bala我最初提供的解决方案实际上并没有阻止这一点。缺失的可重入部分;)是的,这也很好,当我使用getHoldCount()时,brain被卡在了第二档或其他位置:)我的理解是,对于同步方法,第二个调用将被阻止,直到第一个调用完成,然后执行第二个调用。但我的要求是第二次呼叫被忽略。@Bala:没错。在如上所述设置标志时,您需要同步。您还需要执行双重检查锁定:上面的方法在设置和检查标志时很容易出现同步问题。或您可以按照建议使用Lock类。:)@巴拉-鉴于您在对问题的评论中所说的,请注意,来自不同线程的第二个呼叫将被阻止。如果您的方法是从同一线程递归(直接或间接)调用的,那么来自同一线程的第二次调用将不会阻塞。