【发布时间】:2018-07-06 14:30:51
【问题描述】:
我有一个私有的以太坊区块链,上面有 5 台机器进行挖掘。区块链的大小[区块数]截至目前为300。处理在后端Java上完成。
我需要以异步方式运行以下循环构造。循环的瓶颈是在执行以下命令期间:
EthBlock eb = web3.ethGetBlockByNumber(new DefaultBlockParameterNumber(BigInteger.valueOf(i)), true).send();
该命令还可以返回一个Completablefuture<EthBlock> 对象,方法是用这里给出的supplyAsync() 结束它https://github.com/web3j/web3j#start-sending-requests 只需调用supplyAync().get() 即可删除并行性方面并使其同步运行。
public void businessLogic() throws Exception {
recentBlocks = new ArrayList<EthBlock.Block>();
for (long i = 1; i <= 300000; i++) {
EthBlock eb = web3.ethGetBlockByNumber(new DefaultBlockParameterNumber(BigInteger.valueOf(i)), true).send();
if (eb == null || eb.getBlock() == null) {
continue;
}
EthBlock.Block block = eb.getBlock();
recentBlocks.add(block);
}
}
我无法掌握将代码转换为 CompleteableFuture 可以操作的方式的机构。目标是将多个对web.ethGetBlockNumber(...).supplyAync() 的调用“分组”到一个集合中,并一次调用它们以更新将由EthBlock 对象(即recentBlocks)填充的数组。
这是我想出的:
public void businessLogic() throws Exception {
recentBlocks = new ArrayList<EthBlock.Block>();
List<CompleteableFuture> compFutures = new ArrayList<>();
for (long i = 0, i <= 300000, i++){
CompleteableFuture<EthBlock> compFuture = eb3.ethGetBlockByNumber(new DefaultBlockParameterNumber(BigInteger.valueOf(i)), true).sendAsync();
compFuture.thenAcceptAsync(eb -> // Doesn't look right
EthBlock.Block block = eb.getBlock();
recentBlock.add(block);)
compFutures.add(compFuture);
}
CompleteableFuture.allOf(compFutures).get();
}
实现 IntStream
long start = System.nanoTime();
recentBlocks = IntStream.rangeClosed(0, 300_000)
.parallel()
.mapToObj(i -> {
try {
System.out.println("Current Thread -> " + Thread.currentThread());
return web3.ethGetBlockByNumber(new DefaultBlockParameterNumber(BigInteger.valueOf(i)), true).send();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
})
.filter(Objects::nonNull)
.map(EthBlock::getBlock)
.filter(Objects::nonNull)
.collect(Collectors.toList());
long stop = System.nanoTime();
System.out.println("Time Elapsed: " + TimeUnit.MICROSECONDS.convert(stop-start, TimeUnit.NANOSECONDS));
【问题讨论】:
标签: java concurrency blockchain ethereum