Java 同一任务的Junit并行执行

Java 同一任务的Junit并行执行,java,junit,completable-future,Java,Junit,Completable Future,我在代码中发现了一个bug,我知道当20个线程并行运行代码时,有些东西会失败。现在我想为它创建一个测试,但我不知道如何编写它 @Test public void testAuthPerformance() { int numberOfCalls = 20; CompletableFuture<ResponseEntity<OAuth2AccessToken>>[] tasksArray = new CompletableFuture[numberOfCal

我在代码中发现了一个bug,我知道当20个线程并行运行代码时,有些东西会失败。现在我想为它创建一个测试,但我不知道如何编写它

@Test
public void testAuthPerformance() {
    int numberOfCalls = 20;
    CompletableFuture<ResponseEntity<OAuth2AccessToken>>[] tasksArray = new CompletableFuture[numberOfCalls];

    for (int i = 0; i < numberOfCalls; i++) {
        tasksArray[i] = CompletableFuture
                .supplyAsync(() -> new OauthCaller().callAuth(), executorService);
    }

    CompletableFuture.allOf(tasksArray).join();
    for (CompletableFuture<ResponseEntity<OAuth2AccessToken>> task : tasksArray) {
        ResponseEntity<OAuth2AccessToken> responseEntity = task.join();
        assertEquals(HttpStatus.OK, responseEntity.getStatusCode());
    }
}
@测试
公共性能测试(){
int numberOfCalls=20;
CompletableFuture[]tasksArray=新的CompletableFuture[numberOfCalls];
for(int i=0;inew OauthCaller().callAuth(),executorService);
}
CompletableFuture.allOf(tasksArray.join();
用于(可完成的未来任务:tasksArray){
ResponseEntity ResponseEntity=task.join();
assertEquals(HttpStatus.OK,responseEntity.getStatusCode());
}
}
问题是task.join似乎是按顺序而不是并行执行的

在日志中,我可以看到以下在我看来类似于顺序执行的内容:

2017-03-27 13:00:13.263 DEBUG 37381 --- [nio-9999-exec-4] .s.o.p.e.FrameworkEndpointHandlerMapping : Looking up handler method for path /oauth/token
2017-03-27 13:00:13.263 DEBUG 37381 --- [nio-9999-exec-4] .s.o.p.e.FrameworkEndpointHandlerMapping : Returning handler method [public org.springframework.http.ResponseEntity<org.springframework.security.oauth2.common.OAuth2AccessToken> org.springframework.security.oauth2.provider.endpoint.TokenEndpoint.postAccessToken(java.security.Principal,java.util.Map<java.lang.String, java.lang.String>) throws org.springframework.web.HttpRequestMethodNotSupportedException]
2017-03-27 13:00:13.264 DEBUG 37381 --- [nio-9999-exec-4] .o.p.p.ResourceOwnerPasswordTokenGranter : Getting access token for: demo
2017-03-27 13:00:13.342 DEBUG 37381 --- [nio-9999-exec-6] .s.o.p.e.FrameworkEndpointHandlerMapping : Looking up handler method for path /oauth/token
2017-03-27 13:00:13.342 DEBUG 37381 --- [nio-9999-exec-6] .s.o.p.e.FrameworkEndpointHandlerMapping : Returning handler method [public org.springframework.http.ResponseEntity<org.springframework.security.oauth2.common.OAuth2AccessToken> org.springframework.security.oauth2.provider.endpoint.TokenEndpoint.postAccessToken(java.security.Principal,java.util.Map<java.lang.String, java.lang.String>) throws org.springframework.web.HttpRequestMethodNotSupportedException]
2017-03-27 13:00:13.345 DEBUG 37381 --- [nio-9999-exec-6] .o.p.p.ResourceOwnerPasswordTokenGranter : Getting access token for: demo
2017-03-27 13:00:13.482 DEBUG 37381 --- [nio-9999-exec-7] .s.o.p.e.FrameworkEndpointHandlerMapping : Looking up handler method for path /oauth/token
2017-03-27 13:00:13.482 DEBUG 37381 --- [nio-9999-exec-7] .s.o.p.e.FrameworkEndpointHandlerMapping : Returning handler method [public org.springframework.http.ResponseEntity<org.springframework.security.oauth2.common.OAuth2AccessToken> org.springframework.security.oauth2.provider.endpoint.TokenEndpoint.postAccessToken(java.security.Principal,java.util.Map<java.lang.String, java.lang.String>) throws org.springframework.web.HttpRequestMethodNotSupportedException]
2017-03-27 13:00:13.483 DEBUG 37381 --- [nio-9999-exec-7] .o.p.p.ResourceOwnerPasswordTokenGranter : Getting access token for: demo
2017-03-27 13:00:13.263调试37381---[nio-9999-exec-4].s.o.p.e.FrameworkEndpointHandlerMapping:查找路径/oauth/token的处理程序方法
2017-03-27 13:00:13.263调试37381---[nio-9999-exec-4].s.o.p.e.FrameworkEndpointHandlerMapping:返回处理程序方法[public org.springframework.http.ResponseEntity org.springframework.security.oauth2.provider.endpoint.TokenEndpoint.postAccessToken(java.security.Principal,java.util.Map)抛出org.springframework.web.HttpRequestMethodNotSupportedException]
2017-03-27 13:00:13.264调试37381---[nio-9999-exec-4].o.p.p.ResourceOwnerPasswordTokenGranter:获取的访问令牌:演示
2017-03-27 13:00:13.342调试37381---[nio-9999-exec-6].s.o.p.e.FrameworkEndpointHandlerMapping:查找路径/oauth/token的处理程序方法
2017-03-27 13:00:13.342调试37381---[nio-9999-exec-6].s.o.p.e.FrameworkEndpointHandlerMapping:返回处理程序方法[public org.springframework.http.ResponseEntity org.springframework.security.oauth2.provider.endpoint.TokenEndpoint.postAccessToken(java.security.Principal,java.util.Map)抛出org.springframework.web.HttpRequestMethodNotSupportedException]
2017-03-27 13:00:13.345调试37381---[nio-9999-exec-6].o.p.p.ResourceOwnerPasswordTokenGranter:获取的访问令牌:演示
2017-03-27 13:00:13.482调试37381---[nio-9999-exec-7].s.o.p.e.FrameworkEndpointHandlerMapping:查找路径/oauth/token的处理程序方法
2017-03-27 13:00:13.482调试37381---[nio-9999-exec-7].s.o.p.e.FrameworkEndpointHandlerMapping:返回处理程序方法[public org.springframework.http.ResponseEntity org.springframework.security.oauth2.provider.endpoint.TokenEndpoint.postAccessToken(java.security.Principal,java.util.Map)抛出org.springframework.web.HttpRequestMethodNotSupportedException]
2017-03-27 13:00:13.483调试37381---[nio-9999-exec-7].o.p.p.ResourceOwnerPasswordTokenGranter:获取的访问令牌:演示
通过下面的代码,我可以模拟这个问题,但是没有简单的断言方法

ExecutorService executorService = Executors.newFixedThreadPool(20);
try {
    for (int i = 0; i < 20; i++) {
        executorService.execute(() -> new OauthCaller().callAuth());
    }
} finally {
    executorService.shutdown();
}
ExecutorService ExecutorService=Executors.newFixedThreadPool(20);
试一试{
对于(int i=0;i<20;i++){
executorService.execute(()->new OauthCaller().callAuth());
}
}最后{
executorService.shutdown();
}

有人能建议如何对这样的代码进行单元测试吗?谢谢

在加入之前调用集合。无序排列(taskArray)有帮助吗?你怎么知道这不是随机顺序<代码>CompletableFuture.allOf(tasksArray.join()等待所有任务完成,然后按创建顺序检查它们。这并不意味着他们是按那个顺序完成的。如果测试失败了怎么会失败呢?死锁?好的,很抱歉那个订单。我不在乎秩序。我只是想说,任务似乎是按顺序执行的,而不是并行执行的。没有死锁,存在来自
new OauthCaller()的错误状态。callAuth()
对我来说,任务的执行速度似乎比提供和启动任务所需的时间要快。我想你实际上模拟了后端,也许你可以尝试在模拟中添加一些延迟?