提交任务中的值始终相同 - ExecutorService

Value inside submitted task always the same - ExecutorService

我正在创建一个简单的区块链应用程序,我有一个挖掘新区块的方法和一个可以提交挖掘任务的方法。

这是我使用 ExecutorService#submit 提交新任务的方法:

public void executeCommand(int noOfStartingZero) throws ExecutionException, InterruptedException {
        for (int i = 0; i < NO_OF_BLOCKS; i++) {
            executor.submit(() -> {
                Block prevBlock = this.blockchain.getBlocks().peekLast();
                Block block = this.minerCommand.mine(prevBlock, noOfStartingZero);
                System.out.println("block: " + block);
                String minedBy = Thread.currentThread().getName();
                block.setMinedBy(minedBy);
                try {
                    this.blockchain.addNewBlock(block);
                } catch (InvalidBlockException e) {
                    e.printStackTrace();
                }
            });
        }
        executor.shutdown();
 }

问题是,在这条线上,它总是 returns 同一个块: Block block = this.minerCommand.mine(prevBlock, noOfStartingZero);

这是我的 mine() 方法,每次调用它都会创建一个新块:

 public Block mine(Block prevBlock, int noOfStartingZero) {
        if (prevBlock == null) {
            return getGenesisBlock(noOfStartingZero);
        }
        long startTime = System.currentTimeMillis();
        var block = new Block();
        block.setId(prevBlock.id() + 1);
        block.setTimestamp(new Date().getTime());
        block.setPrevHash(prevBlock.hash());

        BlockHashContainer hashContainer = generateHash(block, noOfStartingZero);
        block.setMagicNumber(hashContainer.getMagicNumber());
        block.setHash(hashContainer.getHash());
        block.setTimeGenerated((new Date().getTime() - startTime) / 1000);
        return block;
 }

我尝试为每次迭代打印出块,这就是我得到的,它总是 returns 第一个块,并且没有其他块被添加到区块链中:

block: Block[id=1, timestamp=1632128365538, prevHash=0, hash=818b72956bdb163b5b51b848c2988378cb03bd58649511186ac9a5339d9e392c]
block: Block[id=1, timestamp=1632128365538, prevHash=0, hash=818b72956bdb163b5b51b848c2988378cb03bd58649511186ac9a5339d9e392c]
block: Block[id=1, timestamp=1632128365537, prevHash=0, hash=a840f8f7922fae5b974e1a4e286dbd7247ed19efb12629ba8b0533b117c9451d]
block: Block[id=1, timestamp=1632128365538, prevHash=0, hash=818b72956bdb163b5b51b848c2988378cb03bd58649511186ac9a5339d9e392c]
block: Block[id=1, timestamp=1632128365516, prevHash=0, hash=336385001bb8a9f7b16800fd94e09347dac1a2566bd0edfd0ea6c941b722dd4d]

为什么会这样?任何帮助将不胜感激。

使用 ExecutorService 到 运行 这个操作有可能 运行 每次迭代并发。这意味着在任何任务有机会设置它之前,他们都可以将 prevBlock 视为 null。如果每次迭代都依赖于前一次操作的结果,则根本没有理由使用 ExecutorService。相反,运行 每个挖矿操作在循环内同步进行。