[英]Stop current thread if mutual exclusion detected
在我的android应用程序中,我的一个MODEL类中有一个特定的方法,并且总是从UI线程以外的单独线程中调用此方法。
AlarmManger定期运行此方法,用户也可以选择从UI运行此方法。 (AlarmManger操作和UI操作从除主应用程序UI线程以外的单独线程中调用此方法)。
我只是不想允许同时从UI和AlarmManger运行此方法。
当然,我可以同步该方法,并保证一个线程执行一个方法。 但这不是我想要的。
我想抛出一个异常并停止第二个线程(根据情况可能是UI调用或AlarmManager),如果一个线程已经在执行该方法。 因此,我可以通知用户,由于找到了另一个正在运行的实例(AlarmManger或表单UI)而取消了操作。
请问这种情况下最好的方法是什么? 谢谢
我根据您的问题做出以下假设:
为此,最简单的选项可以是ReentrantLock :: tryLock 。 这样的事情(代码未经过编译或测试。)
class MyClass {
private final ReentrantLock lock = new ReentrantLock();
public void theMethod() {
if(!lock.tryLock()) {
throw new IllegalStateException("Running already");
}
try {
// do stuff
} finally {
lock.unlock();
}
}
}
抛出异常以表明该方法正在执行意味着通过异常执行流控制,这不是一个好习惯。 除非您有保留异常的充分理由,否则我建议这样做:
class MyClass {
private final ReentrantLock lock = new ReentrantLock();
public boolean theMethod() {
if(!lock.tryLock()) {
return false;
}
try {
doStuff();
} finally {
lock.unlock();
}
return true;
}
}
返回值表明该方法是否可以运行,因此调用者可以做出相应的反应。
如果上面的(2)不适用(也就是说,您只想运行一次该方法并确保它永远不会再次执行),则只需执行以下操作:
class MyClass {
private final AtomicBoolean hasExecuted = new AtomicBoolean(false);
public boolean theMethod() {
if(!hasExecuted.compareAndSet(false, true) {
return false; // or throw an exception
}
doStuff();
return true;
}
}
希望对您有所帮助。
为什么不使用信号灯? 您甚至可以使用Java
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.