我不熟悉Java中的多线程,并试图制作一个具有Callable接口和Future Class的Spring项目。
我正在获取dynamo db中的所有记录,对于每条记录,我都是对外部服务的多线程调用。
但是我收到此错误:
嵌套异常是java.util.concurrent.ExecutionException:org.springframework.web.client.HttpServerErrorException:500 null],其根本原因是
我的代码:
控制器:
@Autowired
public RestTemplate restTemplate;
@Autowired
public MyCallable myCallable;
@GetMapping("/myApp-multithread")
public String getQuoteOnSepThread() throws InterruptedException, ExecutionException {
System.out.println("#################################################Multi Threaded Post Call######################");
ExecutorService executor= Executors.newFixedThreadPool(10);
List<Future<String>> myFutureList= new ArrayList<Future<String>>();
long startTime=System.currentTimeMillis()/1000;
Iterable<Customer> customerIterable=repo.findAll();
List<Customer> customers=new ArrayList<Customer>();
customerIterable.forEach(customers::add);
for(Customer c:customers) {
myCallable.sendCustomerToInterface(c);
//System.out.println(c);
Future<String> future= executor.submit(myCallable);
myFutureList.add(future);
}
for(Future<String> fut:myFutureList) {
fut.get();
}
executor.shutdown();
long timeElapsed= (System.currentTimeMillis()/1000)-startTime;
System.out.println("->>>>>>>>>>>>>>>Time Elapsed In Multi Threaded Post Call<<<<<<<<<<<<<<<-"+timeElapsed);
return "Success";
}
MyCallable类:
public class MyCallable implements Callable<String>{
@Autowired
public RestTemplate restTemplate;
//int index=-1;
Customer c= c= new Customer();;
public void sendCustomerToInterface(Customer cust) {
c= cust;
}
@Override
public String call() throws Exception {
System.out.println("Customer no"+ c.getId() +"On thread Number"+Thread.currentThread().getId());
return restTemplate.postForObject("http://localhost:3000/save", c, String.class);
}
}
有人可以帮我吗
编辑:
具有错误的完整堆栈跟踪:
org.springframework.web.client.HttpServerErrorException:500空 在org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:88)〜[spring-web-4.3.13.RELEASE.jar:4.3.13.RELEASE] 在org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:707)〜[spring-web-4.3.13.RELEASE.jar:4.3.13.RELEASE] 在org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:660)〜[spring-web-4.3.13.RELEASE.jar:4.3.13.RELEASE] 在org.springframework.web.client.RestTemplate.execute(RestTemplate.java:620)〜[spring-web-4.3.13.RELEASE.jar:4.3.13.RELEASE] 在org.springframework.web.client.RestTemplate.postForObject(RestTemplate.java:387)〜[spring-web-4.3.13.RELEASE.jar:4.3.13.RELEASE] 在com.OCADemoClient.OCADemoClient.MyCallable.call(MyCallable.java:32)〜[classes /:na] 在com.OCADemoClient.OCADemoClient.MyCallable.call(MyCallable.java:1)〜[classes /:na] 在java.util.concurrent.FutureTask.run(FutureTask.java:266)〜[na:1.8.0_181] 在java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)〜[na:1.8.0_181] 在java.util.concurrent.ThreadPoolExecutor $ Worker.run(ThreadPoolExecutor.java:624)〜[na:1.8.0_181] 在java.lang.Thread.run(Thread.java:748)[na:1.8.0_181]
答案 0 :(得分:1)
根据JavaDoc:
尝试检索因引发异常而中止的任务的结果时引发的异常。
问题似乎出在某些Customer
通话
restTemplate.postForObject("http://localhost:3000/save", c, String.class);
使用HTTP响应代码“ 500”导致服务器错误
我只有在阅读您的评论后才注意到:
您只有一个 MyCallable
,并且在所有Customer
上共享。
这将不起作用,因为您的MyCallable
是有状态对象(它将Customer
与void sendCustomerToInterface(Customer cust)
存储在一起,并且稍后需要在{ {1}}方法。
要使其正常工作,您可以像这样重写Customer
:
call()
,然后在控制器中编写
MyCallable
顺便说一句,您的代码效率低下。您可以跳过生成public class MyCallable implements Callable<String>{
private RestTemplate restTemplate;
private Customer c;
public MyCallable(RestTemplate rt, Customer cust) {
this.restTemplate = rt;
this.c = cust;
}
@Override
public String call() throws Exception {
System.out.println("Customer no"+ c.getId() +"On thread Number"+Thread.currentThread().getId());
return restTemplate.postForObject("http://localhost:3000/save", c, String.class);
}
}
列表,而只写
for(Customer c:customers) {
MyCallable myCallable = new MyCallable(restTemplate, c);
//System.out.println(c);
Future<String> future= executor.submit(myCallable);
myFutureList.add(future);
}