use*_*421 10 java android synchronization
我希望这将是足够的信息,所以在这里.如果您需要更多信息,请在评论中了解.
我有一个有两个内部类的类.内部类每个都有两个方法来调用外部类中的方法.所以,它看起来像这样:
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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
重要的是要注意:
FirstInnerClass,并SecondInnerClass传递给作为网页视图一个JavaScript接口,所以someMethod并someOtherMethod可以随时调用,没有特定的顺序.outerMethod几乎在同一时间被调用(我打印出一条日志消息,并且它们被加时间戳到1000秒)由不同的对象.我的应用程序然后'做东西'两次,因为outerMethodHasBeenCalled在outerMethod被调用时仍然是假的.这不好,这正是我想要阻止的.我的应用程序应该只执行一次"只做一次":第一次outerMethod被调用.OuterClass,但请放心,它只是一个实例OuterClass.重要的是我的应用程序"只会在第一次outerMethod调用时才会执行操作"(我希望现在这一点很明显).所有后续调用基本上都被忽略.无论哪个内部阶级outerMethod首先调用- 都无关紧要.
那么,在这种情况下使用synchronized关键字是否合适?
bre*_*ttw 19
是的,鉴于你上面列出的内容,我会选择:
private synchronized void outerMethod() {
...
}
Run Code Online (Sandbox Code Playgroud)
注意,这将产生阻止其中一个调用者的副作用,直到outerMethod()完成.如果这是可以接受的,很酷.如果意图仅仅是outerMethod()中的代码运行一次,并且如果第一个调用者运行outerMethod(),则第二个调用者没有延迟是可以的,您可以考虑:
public OuterClass {
private AtomicBoolean outerMethodHasBeenCalled = new AtomicBoolean();
private void outerMethod() {
if (outerMethodHasBeenCalled.compareAndSet(false, true)) {
// do stuff
}
}
...
Run Code Online (Sandbox Code Playgroud)
请参阅JavaDoc for AtomicBoolean以了解其中发生的事情(假设它在Android的Java中可用).
outerMethod包含您想要在同步块中只运行一次的所有内容:
private void outerMethod() {
synchronized (this) {
if(!outerMethodHasBeenCalled) {
// do stuff
}
outerMethodHasBeenCalled = true;
}
}
Run Code Online (Sandbox Code Playgroud)
这样,第一次调用该方法时,一次只允许一个线程进入同步块.第一个将在if语句中执行代码,然后设置outerMethodHasBeenCalled为true.其他线程将看到它是真的,并跳过if代码.
| 归档时间: |
|
| 查看次数: |
29033 次 |
| 最近记录: |