When to use synchronized in Java(何时在 Java 中使用同步)
问题描述
我希望这将是足够的信息,所以就这样吧.如果您需要更多信息,请在评论中告诉我.
I hope this is going to be enough information, so here it goes. If you need more info, lemme know in the comments.
我有一个有两个内部类的类.每个内部类都有两个调用外部类中的方法的方法.所以,它看起来像这样:
I have a class that has two inner classes. The inner classes each have two methods that call a method in the outer class. So, it looks like this:
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 应用的.
FirstInnerClass
和SecondInnerClass
的实例作为 JavaScript 接口传递给 WebView,因此可以调用someMethod
和someOtherMethod
随时,不分先后. - 我目前在使用几乎同时调用
outerMethod
的现有代码(没有同步关键字)时遇到问题(我打印出一条日志消息,它们的时间戳记为千分之一秒)由不同的对象.然后我的应用程序做事"两次,因为outerMethodHasBeenCalled
在调用outerMethod
时仍然为假.这是不行的,这正是我想要阻止的.我的应用程序应该只做事"一次:第一次调用outerMethod
. - 听起来我有多个
OuterClass
实例,但请放心,这只是OuterClass
的一个实例.
- This is for an Android app. Instances of
FirstInnerClass
andSecondInnerClass
are passed to a WebView as a JavaScript interface, sosomeMethod
andsomeOtherMethod
can be called at any time, in no particular order. - I currently have a problem with the existing code (without the synchronized keyword) where
outerMethod
is called pretty much at the exact same time (I print out a log message, and they're timestamped to the 1000th of a second) by different objects. My app then 'does stuff' twice becauseouterMethodHasBeenCalled
is still false whenouterMethod
was called. This is not okay, and it is exactly what I'm trying to prevent. My app should only 'do stuff' once and only once: the first timeouterMethod
is called. - It might sound like I have multiple instances of
OuterClass
, but rest assured that it's only one instance ofOuterClass
.
重要的是,我的应用仅在第一次调用 outerMethod
时才做事"(我希望现在已经很明显了).所有后续调用基本上都被忽略了.无论哪个内部类首先调用 outerMethod
- 都无关紧要.
It's important that my app 'does stuff' only the first time outerMethod
gets called (I hope that's evident by now). All subsequent calls are essentially ignored. Whichever inner class calls outerMethod
first -- doesn't matter.
那么,在这种情况下使用 synchronized 关键字是否合适?
So, is it appropriate to use the synchronized keyword in this case?
推荐答案
是的,鉴于您在上面列出的内容,我会选择:
Yup, given what you've laid out above, I'd go with:
private synchronized void outerMethod() {
...
}
注意,这将产生阻塞调用者之一直到 outerMethod() 完成的副作用.如果这是可以接受的,那就酷.如果意图仅仅是 outerMethod() 中的代码运行一次,并且如果第一个调用者正在运行 outerMethod(),则第二个调用者不被延迟是可以的,您可以考虑:
Note, this will have the side-effect of blocking one of the callers until the outerMethod() completes. If that is acceptable, cool. If the intent is merely that the code in outerMethod() is run once, and it is OK for the second caller not to be delayed if the first caller is running outerMethod(), you might consider:
public OuterClass {
private AtomicBoolean outerMethodHasBeenCalled = new AtomicBoolean();
private void outerMethod() {
if (outerMethodHasBeenCalled.compareAndSet(false, true)) {
// do stuff
}
}
...
请参阅 JavaDoc for AtomicBoolean 了解那里发生了什么(假设它在 Android 的 Java 中可用).
See the JavaDoc for AtomicBoolean to grok what is going on there (assuming it is available in Android's Java).
这篇关于何时在 Java 中使用同步的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!