java - 为什么我的并发调用给出 NullPointerException

标签 java multithreading concurrency

这是我的方法:

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/

相关文章:

单一读者和单一作者的 Golang 分配安全

java - 当其中一个找到素数时如何停止线程

java - spring jdbctemplate中查询返回 boolean 值?

DB写操作中的Java并发

c++ - C++项目中的性能测试

python - Pandas、Concurrent.Futures 和 GIL

java - 为什么并发线程限制没有按预期工作?

java - Libgdx 加速度计不工作?

java - Play 框架 - 如何模拟 render() 方法?

java - 使用 String.join() 和 split() 方法替换字符串中的所有元音