我根据您的问题做出以下假设:
- 您想保证方法上的互斥,但如果存在争用,则返回(表示方法未执行),而不是阻塞线程。
- 您需要可重用模型类的实例(例如,假设一旦线程退出该方法,其他线程可以再次调用)
为此,最简单的选项可能是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;
}
}
我希望这会有所帮助。