这是我的方法:
private List<OfficerAccountFilter> createResult(List<Account> accountList) {
List<List<Account>> partedList = Lists.partition(accountList, MAX_LIMIT);
List<OfficerAccountFilter> result = new ArrayList<>();
System.out.println("size of account" + accountList.size());
int size = accountList.size() / 800;
ExecutorService executorService = Executors.newFixedThreadPool(NTHREDS);
List<Future<List<OfficerAccountFilter>>> futureList = new ArrayList<Future<List<OfficerAccountFilter>>>();
for (int i = 0; i <= size + 1; i++) {
Callable<List<OfficerAccountFilter>> worker = new AccountCallable(accountList);
Future<List<OfficerAccountFilter>> submit = executorService.submit(worker);
futureList.add(submit);
}
for (Future<List<OfficerAccountFilter>> future : futureList) {
try {
result = future.get();
} catch (InterruptedException | ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
executorService.shutdown();
return result;
}
我的可调用类:
public class AccountCallable implements Callable<List<OfficerAccountFilter>> {
@Autowired
private OfficerAccountSOAPRunner officerAccountSOAPRunner;
private List<Account> accountList;
public AccountCallable(List<AccountIdentifier> accountList) {
this.accountList = accountList;
}
@Override
public List<OfficerAccountFilter> call() throws Exception {
List<OfficerAccountFilter> result = new ArrayList<>();
for (Account account : accountList) {
OfficerAccountRequest request = new OfficerAccountRequest();
request.getAccounts().add(account);
List<OfficerAccountFilter> accounts = officerAccountSOAPRunner.getAccounts(request);
result.addAll(accounts);
}
return result;
}
}
officerAccountSOAPRunner.getAccounts(request);
这是我调用 Soap 服务的地方,它将过滤后的帐户返回给官员。不确定为什么此时返回 null。如果我按顺序执行,它绝对可以正常工作。我没有正确设置 future 的对象吗?
Error stack:
java.util.concurrent.ExecutionException: java.lang.NullPointerException
at java.util.concurrent.FutureTask.report(FutureTask.java:122)
at java.util.concurrent.FutureTask.get(FutureTask.java:192)
at com.test.service.impl.OfficerServiceImpl.createResult(OfficerServiceImpl.java:92)
at com.test.ServiceImpl.limitOfficerAccounts(OfficerServiceImpl.java:61)
at com.test.service.impl.OfficerServiceImpl.getOfficerAccounts(OfficerServiceImpl.java:54)
Caused by: java.lang.NullPointerException
at com.test.impl.AccountIdentifierCallable.call(AccountCallable.java:36)
at com.test.impl.AccountIdentifierCallable.call(AccountCallable.java:1)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
错误是 SOAPRunner 调用:List<OfficerAccountFilter> accounts = officerAccountSOAPRunner.getAccounts(request);
我将它置于 Debug模式,一旦我设置为@Autowired,它就会出现。所以它来自那里。我需要设置不同的上盖吗?
最佳答案
NullPointerException
是因为您在可调用对象中 Autowiring soap 服务:
@Autowired
private OfficerAccountSOAPRunner officerAccountSOAPRunner;
您正在自己创建 AccountCallable
的实例,而不是从 Spring 获取它们,这是正确的,因为您需要自己创建可调用对象。但是 Spring 无法帮助您 Autowiring soap runner。因此,当您在 createResult
方法中创建它的实例时,您应该将 OfficerAccountSOAPRunner
作为构造函数参数传递给您的可调用对象。
您可以在包含 createResult
方法的类中获取 Autowiring 的 OfficerAccountSOAPRunner
,这样它就可以将它传递给 AccountCallable
对象它创造了它们。
附带说明一下,您不需要创建多个可调用对象。以下内容:
for (int i = 0; i <= size + 1; i++) {
Callable<List<OfficerAccountFilter>> worker = new AccountCallable(accountList);
Future<List<OfficerAccountFilter>> submit = executorService.submit(worker);
futureList.add(submit);
}
可以替换为:
Callable<List<OfficerAccountFilter>> worker = new AccountCallable(accountList);
Future<List<OfficerAccountFilter>> future = executorService.submit(worker);
然后就可以得到单一future的结果:
future.get();
关于java - 为什么我的并发调用给出 NullPointerException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39213296/