1

我有一个类,该类具有其他类使用的一个功能。我觉得我的函数是从不同步的线程调用的。在我的函数中添加繁忙标志以防止从不同步的线程调用是一个很好的解决方案。它会起作用吗:

public class Hndl
{
boolean isBusy=false;

    public  boolean doJob()
    {
        if(!isBusy)
        {
        isBusy=true;
        ...
            return true;
        isBusy=false;
        }
        else
        {
            return false;
        }
    }


}
4

2 回答 2

3

除非您确实需要busy在类的其他方法中使用该标志,否则您可能应该简单地定义您的方法synchronized以避免它被并行执行并使其thread-safe

public synchronized boolean doJob() { ... }
于 2013-07-04T08:32:12.630 回答
2

这是不安全的,因为这个顺序是可能的:

thread 1 reads busy flag: not busy
thread 2 reads busy flag: not busy
thread 1 sets busy flag to busy
thread 2 sets busy flag to busy

both threads execute the method

要解决此问题,您可以使用双重检查锁定,这需要制作标志volatile否则它也会失败,或者使用锁定

Lock isBusy = new ReentrantLock();

public boolean doJob()
{
    if (isBusy.tryLock()) {
        try {
            ...
            return true;
        } finally {
            isBusy.unlock();
        }
    }
    else
    {
        return false;
    }
}

如果您使用该方法synchronized而不是使用锁,那么线程 2 将不得不等到线程 1 退出该方法而不是立即返回,这不是您的程序尝试做的事情。

于 2013-07-04T08:36:26.387 回答