在压力测试下,函数在同时调用中具有不同的行为

时间:2017-11-07 09:01:37

标签: java multithreading load-testing stress-testing

我在软件中发现了一个只在压力测试中发生的错误。如果呼叫同时或几乎同时发生,则调用大量函数并具有不同的行为。

我举了一个例子来说明发生了什么:

public void doPayment(Acccount account) throws MyException {

    if (isMoneyAvailable(account)) {
        confirmPayment(account);
    }else{
        throw new MyException(myErrorCode);
    }
}

如果同时调用此功能两次,则只需支付一笔款项,即可完成两笔付款。

你有什么想法可以防止这种错误吗?

4 个答案:

答案 0 :(得分:1)

您最简单的解决方案可能是同步它:

public synchronized void doPayment(Acccount account) throws MyException {

    if (isMoneyAvailable(account)) {
        confirmPayment(account);
    } else {
        throw new MyException(myErrorCode);
    }
}

这将确保任何时候只有一个线程可以在此对象中使用此方法。

这可能不是你想要的。例如,如果您有多个包含此方法的对象(可能在超类中),那么您应该使用不同的机制。

你应该学习并发和同步,以确保你做对了。众所周知,并发问题很难追查。

答案 1 :(得分:1)

您可以仅在帐户对象上进行同步,而不是在整个方法上进行同步。这样做会更好。这主要是因为我们不希望多个线程同时访问帐户对象。只要他们访问不同的帐户对象,他们就不应该互相阻止。

public void doPayment(Acccount account) throws MyException {
    synchronized(account){
    if (isMoneyAvailable(account)) {
        confirmPayment(account);
    }else{
        throw new MyException(myErrorCode);
    }
}
}

答案 2 :(得分:0)

使用同步

public void doPayment(Acccount account) throws MyException {
    synchronized(key){
    if (isMoneyAvailable(account)) {
        confirmPayment(account);
    }else{
        throw new MyException(myErrorCode);
    }
}
}

答案 3 :(得分:0)

我不是多线程计算方面的专家,但你必须考虑到这个调用有并发性。 基本上我认为你可以简单地这样做:

public synchronized void doPayment(Acccount account) throws MyException {

    if (isMoneyAvailable(account)) {
        confirmPayment(account);
    }else{
        throw new MyException(myErrorCode);
    }
}

在不知道包含此方法的类的任何其他内容的情况下,这是我最好的答案。不同之处在于关键字“syncronized”允许java将“doPayment”调用为原子操作,因此没有人可以干涉。 有关同步的更好解释,请查看java reference about it

最好的问候。