在java中有没有其他/更好的方法来实现这个简单的逻辑?

在java中有没有其他/更好的方法来实现这个简单的逻辑?,java,Java,我有一个方法,比如method1(),需要一段时间才能运行。在执行过程中,如果有另一个对method1()的调用,则应该忽略它。大致上,我有这样的想法 boolean mFlag = false; void method1() { if(!mFlag) { mFlag=true; // do Stuff mFlag=false; } } 这很有效

我有一个方法,比如method1(),需要一段时间才能运行。在执行过程中,如果有另一个对method1()的调用,则应该忽略它。大致上,我有这样的想法

    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类。:)@巴拉-鉴于您在对问题的评论中所说的,请注意,来自不同线程的第二个呼叫将被阻止。如果您的方法是从同一线程递归(直接或间接)调用的,那么来自同一线程的第二次调用将不会阻塞。