【问题标题】:Passing Class that runs task to Completable Future SupplyAsync将运行任务的类传递给 Completable Future SupplyAsync
【发布时间】:2022-12-01 18:18:39
【问题描述】:

尝试比较期货与已完成期货的实施,并检查可完成期货的非阻塞性质是否是解决我的问题的更好用例。让我的可完成实现正常工作时遇到问题。

        Collection<Future<ArrayList<MeterTariffValues>>> futures = new ArrayList<>();

        List<CompletableFuture<GetSiteMeterTariffValues>> completableFutures = new ArrayList<>(); 


        for (Site site : sites) {
            completableFutures.add(
                CompletableFuture.supplyAsync(new Supplier<GetSiteMeterTariffValues>() {
                    @Override
                    public GetSiteMeterTariffValues get() {
                        return  new GetSiteMeterTariffValues(
                            site.getSite_id(),
                            methaneConversionVal,
                            nitrogenConversionVal,
                            bu_id,
                            region_id,
                            facility_id,
                            status,
                            resource_id,
                            metertype_id,
                            currentCalendarYear,
                            currentFiscalYear,
                            fiscalYearStartMonth,
                            dates,
                            meterMapper,
                            sqlSessionTemplate);
                    }
                }, taskExecutor)
            );
            
            futures.add(
                    taskExecutor.submit(
                            new GetSiteMeterTariffValues(
                                    site.getSite_id(),
                                    methaneConversionVal,
                                    nitrogenConversionVal,
                                    bu_id,
                                    region_id,
                                    facility_id,
                                    status,
                                    resource_id,
                                    metertype_id,
                                    currentCalendarYear,
                                    currentFiscalYear,
                                    fiscalYearStartMonth,
                                    dates,
                                    meterMapper,
                                    sqlSessionTemplate)));
        }

Completable 实现的问题在于,它无法识别 GetSiteMeterTariffValues 在任务完成后返回不同的类型。

它返回

public ArrayList<MeterTariffValues> call() 

但是任务执行者对此很好

        for (Future<ArrayList<MeterTariffValues>> future : futures) {

            long start = System.currentTimeMillis();
            ArrayList<MeterTariffValues> siteMeterTariffMonthlyValues = future.get();
            long end = System.currentTimeMillis();
            long totalMS = end - start;
            total += totalMS;
            meterTariffValues.addAll(siteMeterTariffMonthlyValues);
        }

所以我想知道我如何用 completablefutures 做类似的事情。

注意:GetSiteMeterTariffValues 实现了 Callable<ArrayList>

【问题讨论】:

  • 请说清楚“GetSiteMeterTariffValues 在任务完成后返回不同的类型”
  • 我可能实际上只需要调用 call 方法。

标签: java concurrency completable-future


【解决方案1】:

CompletableFuture.supplyAsync() 期望 Supplier 相当于 Callable 对于 ExecutorService

你目前这样做的方式,你只是提供一个创建CallableSupplier,但当然你的CallableGetSiteMeterTariffValues)不会被调用。

你只需要让GetSiteMeterTariffValues实现Supplier并直接在CompletableFuture.supplyAsync()中使用它:

CompletableFuture.supplyAsync(
    new GetSiteMeterTariffValues(
        site.getSite_id(),
        methaneConversionVal,
        nitrogenConversionVal,
        bu_id,
        region_id,
        facility_id,
        status,
        resource_id,
        metertype_id,
        currentCalendarYear,
        currentFiscalYear,
        fiscalYearStartMonth,
        dates,
        meterMapper,
        sqlSessionTemplate),
    taskExecutor)

请注意Supplier 不允许抛出已检查的异常,因此您不能只使用对Callable.call() 的方法引用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多