Java - 如何知道当前是否正在运行特定方法

nik*_*nik 1 java

我有 2 个 Web 应用程序:Application1 和 Application2——都是 REST 应用程序。

Application1 有时会调用 Application2 中的方法。

这是非常重要的部分 - 只有这个方法的一个实例应该同时运行。因此,在从 Application1 调用 Application2 中的方法之前,会调用额外的请求来测试方法是否在当前时刻运行。

现在我以这种方式实现它(它不是实际代码 - 这只是为了大致显示实际代码的作用):

static Boolean ifRunning = false;

static void methodWrapper() throws Exception {

    try {
        ifRunning = true;
        method();
    } finally {
        ifRunning = false;
    }
}

static void method() {
    // do something
}

static Boolean monitorMethod() {
    return ifRunning;
} 
Run Code Online (Sandbox Code Playgroud)

在这段代码中:

  • "method" - 该方法只有一个实例应该同时运行
  • "monitorMethod" - 此方法用于监控

这不是最好的解决方案:“methodWrapper”中的“finally”可能不会执行(在某些情况下 - 例如 System.exit(0)),因此在某些时候“ifRunning”可以在方法结束时保持为真。结果从那一刻开始,Application1 认为该方法一直在运行。

那么对于我的目标有更好的解决方案吗?

And*_*ner 6

您的代码的问题在于,如果从多个线程调用它,它将无法正常工作:不能保证其他线程会看到running.

您可以使用Semaphore

static final Semaphore running = new Semaphore(1);

static void methodWrapper() throws Exception {
    if (!running.tryAcquire()) {
        throw new Exception("Already running!!!");
    }
    try {
        method();
    } finally {
        running.release();
    }
}
Run Code Online (Sandbox Code Playgroud)

缺点Semaphore是您无法查询它以查看是否正在运行。相反,您可以使用AtomicBoolean

static final AtomicBoolean running = new AtomicBoolean();

static void methodWrapper() throws Exception {
    if (!running.compareAndSet(false, true)) {
        throw new Exception("Already running!!!");
    }
    try {
        method();
    } finally {
        running.set(false);
    }
}
Run Code Online (Sandbox Code Playgroud)

现在您获得与信号量大致相同的行为,但您可以调用running.get()以查看当时是否有任何东西正在运行该方法。