提交任务中的值始终相同 - 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
。相反,运行 每个挖矿操作在循环内同步进行。
我正在创建一个简单的区块链应用程序,我有一个挖掘新区块的方法和一个可以提交挖掘任务的方法。
这是我使用 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
。相反,运行 每个挖矿操作在循环内同步进行。