我希望这将是足够的信息,所以就在这里。如果您需要更多信息,请在评论中了解。

我有一类有两个内部类。内部类每个都有两个方法来调用外部类中的方法。因此,它看起来像这样:

public OuterClass {
    private boolean outerMethodHasBeenCalled = false;

    private void outerMethod() {
        if(!outerMethodHasBeenCalled) {
            // do stuff
        }

        outerMethodHasBeenCalled = true;
    }

    private FirstInnerClass {
        public void someMethod() {
            outerMethod();
        }
    }

    private SecondInnerClass {
        public void someOtherMethod() {
            outerMethod();
        }
    }
}

重要的是要注意:
  • 这是一个Android应用程序。 FirstInnerClassSecondInnerClass的实例作为JavaScript接口(interface)传递到WebView,因此可以随时以特定顺序调用someMethodsomeOtherMethod
  • 我目前对现有代码(没有synced关键字)有问题,其中outerMethod在完全相同的时间(我打印出一条日志消息,并且它们被时间戳记到1000秒)几乎在同一时间被调用。然后我的应用程序“执行”操作两次,因为调用outerMethodHasBeenCalledouterMethod仍然为false。这不行,这正是我要防止的事情。我的应用程序只能“执行一次”,并且只能一次:第一次调用outerMethod
  • 听起来好像我有OuterClass的多个实例,但是请放心,它只是OuterClass的一个实例。

  • 重要的是,我的应用程序仅在第一次调用outerMethod时才“执行操作”(我希望现在可以证明这一点)。本质上,所有后续调用都将被忽略。哪个内部类首先调用outerMethod都没关系。

    那么,在这种情况下使用synced关键字是否合适?

    最佳答案

    是的,鉴于您在上面已列出的内容,我会考虑:

    private synchronized void outerMethod() {
    ...
    }
    

    请注意,这将具有阻塞调用者之一,直到externalMethod()完成之前的副作用。如果可以接受,请冷却。如果目的只是让outerMethod()中的代码运行一次,并且如果第一个调用者正在运行outerMethod(),则第二个调用者不延迟也可以,您可以考虑:
    public OuterClass {
        private AtomicBoolean outerMethodHasBeenCalled = new AtomicBoolean();
    
        private void outerMethod() {
            if (outerMethodHasBeenCalled.compareAndSet(false, true)) {
                // do stuff
            }
        }
    ...
    

    查看JavaDoc for AtomicBoolean以了解发生了什么(假设它在Android的Java中可用)。

    07-26 07:36