首页 文章

每个Java Future控制其生命周期的核心

提问于
浏览
0

我正在使用web3j库在Java中为以太坊区块链开发一个Load Test应用程序 . 此库中使用的特定函数,异步发送事务,并返回Future对象 . 该库提供了许多功能,这些功能最初满足我对应用程序开发的所有需求 . 但是,在设计和重新设计负载测试应用程序之后,我注意到了一个问题 . 我只能同时部署N个Futures,其中N是我机器上可用内核的数量 .

这是非常低效的,因为每个事务至少需要10秒才能集成到区块链中,而Futures会在后台持续运行 . 如果它们被转换为RxJava observables(使用RxJava的from()函数),它们是否仍然会在后台连续运行以检查它们的数据是否可用,或者我是否能够一次覆盖多个检查 . 例如,如果检查需要0.1秒,并且我需要每秒检查一次,那么我可以在一个核心而不是1上运行10次检查 . 如果将Future转换为Observable仍然会显示连续核心使用行为,有没有不同的方法来解决这个问题,而不涉及重构很多web3j内部代码?

罪魁祸首可能是这个函数,包含在Async.java文件中 . 内部web3j函数调用此函数来发送事务 .

public static <T> CompletableFuture<T> run(Callable<T> callable) {
    CompletableFuture<T> result = new CompletableFuture<>();
    CompletableFuture.runAsync(() -> {
        // we need to explicityly catch any exceptions,
        // otherwise they will be silently discarded
        try {
            result.complete(callable.call());
        } catch (Throwable e) {
            result.completeExceptionally(e);
        }
    });
    return result;
}

1 回答

  • 2

    首先,如果您希望任务返回结果,则应使用 supplyAsync 而不是 runAsync .

    但是在你问题的更实质性部分,当你只调用要运行的任务调用 runAsyncsupplyAsync 时,它将在JVM范围内运行 ForkJoinPool ,正如你所猜测的那样,它有多少线程可用,而核心就是你的机器 . 但是,您也可以选择 ExecutorService ,这可能比核心更多 .

    ExecutorService executor = Executors.newFixedThreadPool(NUM_DESIRED_THREADS);
    
    CompletableFuture<T> result = CompletableFuture.supplyAsync(callable, executor);
    

    上面的代码将允许同时运行多达 NUM_DESIRED_THREADS 个任务 .

相关问题