Java 在压力测试下,函数在同时调用中具有不同的行为
我在一个软件中发现了一个只在压力测试下才会发生的错误。一个函数被大量调用,如果调用同时或几乎同时进行,则具有不同的行为 我用一个例子来说明发生了什么:Java 在压力测试下,函数在同时调用中具有不同的行为,java,multithreading,load-testing,stress-testing,Java,Multithreading,Load Testing,Stress Testing,我在一个软件中发现了一个只在压力测试下才会发生的错误。一个函数被大量调用,如果调用同时或几乎同时进行,则具有不同的行为 我用一个例子来说明发生了什么: public void doPayment(Acccount account) throws MyException { if (isMoneyAvailable(account)) { confirmPayment(account); }else{ throw new MyException(m
public void doPayment(Acccount account) throws MyException {
if (isMoneyAvailable(account)) {
confirmPayment(account);
}else{
throw new MyException(myErrorCode);
}
}
如果同时调用此函数两次,则当帐户只有一次付款的钱时,将完成两次付款
您知道我如何防止此类错误吗?您最简单的解决方案可能是同步:
public synchronized void doPayment(Acccount account) throws MyException {
if (isMoneyAvailable(account)) {
confirmPayment(account);
} else {
throw new MyException(myErrorCode);
}
}
这将确保在任何时候只有一个线程可以在此对象中使用此方法
这可能不是你想要的。例如,如果有多个对象包含此方法(可能在超类中),则应使用不同的机制
您应该研究并发性和同步性,以确保它是正确的。众所周知,并发问题很难追踪。最简单的解决方案可能是同步它:
public synchronized void doPayment(Acccount account) throws MyException {
if (isMoneyAvailable(account)) {
confirmPayment(account);
} else {
throw new MyException(myErrorCode);
}
}
这将确保在任何时候只有一个线程可以在此对象中使用此方法
这可能不是你想要的。例如,如果有多个对象包含此方法(可能在超类中),则应使用不同的机制
您应该研究并发性和同步性,以确保它是正确的。众所周知,并发问题很难追踪。使用同步
public void doPayment(Acccount account) throws MyException {
synchronized(key){
if (isMoneyAvailable(account)) {
confirmPayment(account);
}else{
throw new MyException(myErrorCode);
}
}
}
使用同步
public void doPayment(Acccount account) throws MyException {
synchronized(key){
if (isMoneyAvailable(account)) {
confirmPayment(account);
}else{
throw new MyException(myErrorCode);
}
}
}
我不是一个关于多线程计算的专家,但是你必须考虑到你建议的这个调用的并发性。 基本上,我认为你可以这样做:
public synchronized void doPayment(Acccount account) throws MyException {
if (isMoneyAvailable(account)) {
confirmPayment(account);
}else{
throw new MyException(myErrorCode);
}
}
在不知道任何其他包含此方法的类的情况下,这是我最好的答案。区别在于关键字“syncronized”允许java将“doPayment”调用为原子运算,因此没有人可以干预。
要更好地解释同步,请查看java
<>诚挚的问候。 < p>我不是一个多线程计算专家,但是你必须考虑到你建议的这个调用的并发性。 基本上,我认为你可以这样做:
public synchronized void doPayment(Acccount account) throws MyException {
if (isMoneyAvailable(account)) {
confirmPayment(account);
}else{
throw new MyException(myErrorCode);
}
}
在不知道任何其他包含此方法的类的情况下,这是我最好的答案。区别在于关键字“syncronized”允许java将“doPayment”调用为原子运算,因此没有人可以干预。
要更好地解释同步,请查看java
致以最诚挚的问候。您可以只在account对象上进行同步,而不是在整个方法上进行同步。这样它的表现会更好。这主要是因为我们不希望多个线程同时访问account对象。只要它们正在访问不同的帐户对象,就不应该互相阻塞
public void doPayment(Acccount account) throws MyException {
synchronized(account){
if (isMoneyAvailable(account)) {
confirmPayment(account);
}else{
throw new MyException(myErrorCode);
}
}
}
您可以只在account对象上同步,而不是在整个方法上同步。这样它的表现会更好。这主要是因为我们不希望多个线程同时访问account对象。只要它们正在访问不同的帐户对象,就不应该互相阻塞
public void doPayment(Acccount account) throws MyException {
synchronized(account){
if (isMoneyAvailable(account)) {
confirmPayment(account);
}else{
throw new MyException(myErrorCode);
}
}
}
了解Java中的并发和同步。快速而肮脏的解决方案是在方法签名中添加
synchronized
关键字。但是,对任何半真半假的Java程序员来说,并发应该是基础知识。了解Java中的并发和同步。快速而肮脏的解决方案是在方法签名中添加synchronized
关键字。但是,对任何半真半假的Java程序员来说,并发应该是基础知识,不管key
应该是什么,它似乎是不必要的,您可以在上同步这个。如果将整个方法体包装在一个synchronized
中,则可以同步整个方法instead@Turing85但我认为同步方法不是一个好方法practice@Turing85在上同步此
,然后两个不相关的方法在多线程上下文中相互阻塞。Bad advice.key最好是我在回答中描述的account对象。我同意解决办法。只是他没有提到关键应该是账户object@akshayapandey密钥不是帐户对象,它只是一个对象。请检查并发性和密钥无论Key
应该是什么,它似乎是不必要的,您可以在上同步此。如果将整个方法体包装在一个synchronized
中,则可以同步整个方法instead@Turing85但我认为同步方法不是一个好方法practice@Turing85在上同步此
,然后两个不相关的方法在多线程上下文中相互阻塞。Bad advice.key最好是我在回答中描述的account对象。我同意解决办法。只是他没有提到关键应该是账户object@akshayapandey密钥不是帐户对象,它只是一个对象。请检查并发性和密钥