简体   繁体   English

从异步方法返回 object 到 CompletableFuture<object> 列表?<div id="text_translate"><p> 我有一个要使用异步方法处理的对象列表(来自 model class 名称)。 异步方法将获取列表中的每个名称 object 并对其进行处理(检查它是否未被占用),我希望在所有名称都被异步方法处理后返回到isNameAvailable(LinkedHashSet<Name> nameList)方法</p><p>我的执行者配置</p><pre>@Configuration @ManagedResource public class ThreadConfig { @Bean(name = "nameAvailabilityExecutor") public Executor nameAvailabilityExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(100); executor.setMaxPoolSize(1200); executor.setQueueCapacity(10000); executor.setThreadNamePrefix("nameAvailabilityExecutor-"); executor.initialize(); return executor; } }</pre><p> 服务 class 将调用另一个 class 中的异步方法</p><pre>public LinkedHashSet<Name> isNameAvailable(LinkedHashSet<Name> nameList) { LinkedHashSet<Name> nameCheckedList = new LinkedHashSet<>(); for (Name nameObj: nameList) { Name nameCheckedObj = domainAvailabilityServiceThread.isNameAvailable(nameObj); nameCheckedList.add(nameCheckedObj); } return nameCheckedList; }</pre><p> 将进行处理的异步方法</p><pre>@Async("nameAvailabilityExecutor") public Name isNameAvailable(Name nameObj) { String name = nameObj.getName(); if (getByNameCheck(name)) { nameObj.setAvailable(true); } else { nameObj.setAvailable(false); } return nameObj; }</pre><p> 根据我的理解 CompletableFuture 是我需要在这里使用的吗? 在这种情况下使用 CompletableFuture 的正确方法是什么?</p></div></object>

[英]Return object from async method into CompletableFuture<Object> list?

I have a list of objects (from model class Name) that I want to process using an async method.我有一个要使用异步方法处理的对象列表(来自 model class 名称)。 The async method will take each Name object in the list and process it (check if it's not taken), I want to have a list of Names after they all get processed by the async method to get returned to the isNameAvailable(LinkedHashSet<Name> nameList) method异步方法将获取列表中的每个名称 object 并对其进行处理(检查它是否未被占用),我希望在所有名称都被异步方法处理后返回到isNameAvailable(LinkedHashSet<Name> nameList)方法

My executor config我的执行者配置

@Configuration
@ManagedResource
public class ThreadConfig {
    @Bean(name = "nameAvailabilityExecutor")
    public Executor nameAvailabilityExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(100);
        executor.setMaxPoolSize(1200);
        executor.setQueueCapacity(10000);
        executor.setThreadNamePrefix("nameAvailabilityExecutor-");
        executor.initialize();
        return executor;
    }
}

Service class which will call the Async method in another class服务 class 将调用另一个 class 中的异步方法

public LinkedHashSet<Name> isNameAvailable(LinkedHashSet<Name> nameList) {
    LinkedHashSet<Name> nameCheckedList = new LinkedHashSet<>();

    for (Name nameObj : nameList) {
        Name nameCheckedObj = domainAvailabilityServiceThread.isNameAvailable(nameObj);
        nameCheckedList.add(nameCheckedObj);
    }

    return nameCheckedList;
}

The async method which will do the processing将进行处理的异步方法

@Async("nameAvailabilityExecutor")
public Name isNameAvailable(Name nameObj) {
    String name = nameObj.getName();

    if (getByNameCheck(name)) {
        nameObj.setAvailable(true);
    } else {
        nameObj.setAvailable(false);
    }

    return nameObj;
}

From my understanding CompletableFuture is what I need to use here?根据我的理解 CompletableFuture 是我需要在这里使用的吗? What is the correct way using CompletableFuture in this scenario?在这种情况下使用 CompletableFuture 的正确方法是什么?

You can simply make isNameAvailable(Name) return a CompletableFuture :你可以简单地让isNameAvailable(Name)返回一个CompletableFuture

@Async("nameAvailabilityExecutor")
public CompletableFuture<Name> isNameAvailable(Name nameObj) {
    String name = nameObj.getName();

    if (getByNameCheck(name)) {
        nameObj.setAvailable(true);
    } else {
        nameObj.setAvailable(false);
    }

    return CompletableFuture.completedFuture(nameObj);
}

Spring @Async will deal with the asynchronous execution as you intended. Spring @Async将按照您的预期处理异步执行。

You will also need to change the return type of isNameAvailable(LinkedHashSet) to a simple List or something similar, since it does not really make sense to store CompletableFuture s in a Set :您还需要将isNameAvailable(LinkedHashSet)的返回类型更改为简单的List或类似的东西,因为将CompletableFuture存储在Set中实际上没有意义:

public List<CompletableFuture<Name>> isNameAvailable(LinkedHashSet<Name> nameList) {
    List<CompletableFuture<Name>> nameCheckedList = new ArrayList<>();

    for (Name nameObj : nameList) {
        CompletableFuture<Name> nameCheckedObj = domainAvailabilityServiceThread.isNameAvailable(nameObj);
        nameCheckedList.add(nameCheckedObj);
    }

    return nameCheckedList;
}

Note that it is probably not a good idea to asynchronously modify the state of an object like you are doing here with Name , as it makes it more difficult to guarantee what state will be visible to the calling thread.请注意,异步修改 object 的 state 可能不是一个好主意,就像您在此处使用Name所做的那样,因为这使得更难以保证 state 对调用线程可见。 It might be preferable to work with CompletableFuture<Boolean> :使用CompletableFuture<Boolean>可能更可取:

@Async("nameAvailabilityExecutor")
public CompletableFuture<Boolean> isNameAvailable(Name nameObj) {
    String name = nameObj.getName();

    return CompletableFuture.completedFuture(getByNameCheck(name));
}

and return a Map<Name, CompletableFuture<Boolean>> :并返回一个Map<Name, CompletableFuture<Boolean>>

public Map<Name, CompletableFuture<Boolean>> isNameAvailable(LinkedHashSet<Name> nameList) {
    Map<Name, CompletableFuture<Boolean>> nameCheckedList = new HashMap<>();

    for (Name nameObj : nameList) {
        CompletableFuture<Boolean>> nameCheckedObj = domainAvailabilityServiceThread.isNameAvailable(nameObj);
        nameCheckedList.put(nameObj, nameCheckedObj);
    }

    return nameCheckedList;
}

and let the calling thread do whatever is needed with that check.并让调用线程执行该检查所需的任何操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM