当用户试图在多线程上下文中使用类的非线程安全方法时,有没有办法抛出异常?我猜问题主要是检测到多个线程正在尝试使用该方法。或者,有没有可以在函数声明中使用的"not_synchronous“关键字/标记?
发布于 2012-07-31 16:07:53
没有简单的方法可以做到这一点,不。如果您检测到多个线程正在使用一个方法,那么很有可能您必须使用线程安全集合等。如果你正在做所有这些事情,那么你可能不得不让方法本身成为线程安全的。
发布于 2012-07-31 16:18:37
在允许线程运行该方法之前,您可以检查该方法是否已在使用中--但这与使用锁没有太大区别(注意:我的示例不是可重入的):
private static final AtomicBoolean used = new AtomicBoolean();
public static void unsafe() throws InterruptedException {
if(!used.compareAndSet(false, true)) {
throw new IllegalStateException();
}
//do you stuff
used.set(false);
}
发布于 2012-07-31 16:22:00
对Gray的回答进行扩展:假设您想这样做(检测一个方法何时正被多个线程使用)。一个简单的(不正确的)实现可能如下所示:
volatile boolean methodBeingUsed = false;
public void doSomething() {
if (methodBeingUsed) throw new IllegalStateException("You can't do that!");
try {
methodBeingUsed = true;
// do something...
} finally {
methodBeingUsed = false;
}
}
好吧,好吧..。但是两个线程可以同时通过第一次if (methodBeingUsed)
检查并进入临界区。因此,现在我们可以尝试添加一个锁来保护methodBeingUsed
标志:
Lock methodLock = new ReentrantLock();
volatile boolean methodBeingUsed = false;
public void doSomething() {
try {
lock.lock();
if (methodBeingUsed) throw new IllegalStateException("You can't do that!");
methodBeingUsed = true;
} finally {
lock.unlock();
}
try {
// do something...
} finally {
try {
lock.lock();
methodBeingUsed = false;
} finally {
lock.unlock();
}
}
}
当然,这假设doSomething()不能递归地调用自身。如果可以,那么您还必须跟踪调用线程。添加更多的检查,以说明我现在没有考虑到的其他情况,很容易看出,花在同步逻辑上的精力来检测多线程正在使用的方法,最好从一开始就让方法是线程安全的。
https://stackoverflow.com/questions/11744392
复制相似问题