我在使用 nextMessageId() 時遇到問題,它應該為創建的每條訊息回傳一個新 ID。然而,每隔一段時間它就不會。它回傳一個已經使用過的值,我不明白為什么。我已經嘗試在 IDE 中除錯它,但是當我逐步除錯它時它似乎作業正常。
我正在嘗試學習如何使用多個執行緒,如何正確同步方法等。我正在模擬用戶發送訊息的程序。
基本上每次挖出一個塊時,都會將訊息從緩沖區復制到當前塊,然后將新塊添加到塊集合中。除了 nextMessageId() 之外,一切似乎都正常。任何幫助表示贊賞。
我不想發布不必要的代碼來保持這篇文章盡可能干凈,如果需要更多資訊,請告訴我。
用戶服務類:
public final class UserService extends Service<User, String> {
...
@Override
public void submit(String message, User user) {
synchronized (Blockchain.class) {
MessageEntry messageEntry = MessageEntry.newInstance(repo.nextMessageId(), message, user);
repo.postMessage(messageEntry);
}
}
}
礦工服務類:
public final class MinerService extends Service<Miner, Long> {
...
public void submit(Long number, Miner miner) {
if (repo.getCurrentBlock().hash(number).startsWith(repo.prefix())) {
synchronized (Blockchain.class) {
if (repo.getCurrentBlock().hash(number).startsWith(repo.prefix())) {
repo.createBlock(number, miner);
}
}
}
}
}
Blockchain.class
public class Blockchain {
...
private Deque<Block> blocks;
private Deque<DataEntry<?>> messageBuffer;
private Block currentBlock;
...
public long nextMessageId() {
return blocks.stream()
.mapToLong(block -> block.getData().size())
.sum() messageBuffer.size() 1L;
}
public void postMessage(DataEntry<?> dataEntry) {
messageBuffer.offerLast(dataEntry);
}
public void createBlock(long number, Miner miner) {
long duration = (new Date().getTime() - currentBlock.getTimestamp()) / 1000;
Block.ProofOfWork proofOfWork = new Block.ProofOfWork(number, duration, updateN(duration), miner);
currentBlock.setProofOfWork(proofOfWork);
if (blocks.offerLast(currentBlock)) {
currentBlock = generateBlock();
currentBlock.setData(messageBuffer);
messageBuffer.clear();
stateManager.save();
}
}
...
}
生成 5 個區塊后的 Message 輸出:
Block:
Created by miner # 4
Id: 1
Timestamp: 1637995160818
Magic number: 6489039085832314491
Hash of the previous block:
0
Hash of the block:
7cecb0d73c5bbfa925f2c04fba90778c8431e43dc3abd1b0faf1dbc23400321c
Block data: no messages
Block was generating for 0 seconds
N was increased to 1
Block:
Created by miner # 6
Id: 2
Timestamp: 1637995160897
Magic number: 5017000130559711273
Hash of the previous block:
7cecb0d73c5bbfa925f2c04fba90778c8431e43dc3abd1b0faf1dbc23400321c
Hash of the block:
0ff1a96574cd8cf9db8c91eeb436df8efd084582251c081409e43e0f17069d51
Block data:
1 Charles: Life is good
2 Aramys: How bout' those Dolphins?
3 Evelio: Life is good
4 Armando: I love Java
5 Evelio: I love Java
6 Armando: What is the meaning of life?
7 Aramys: I love basketball
8 Charles: How bout' those Dolphins?
Block was generating for 0 seconds
N was increased to 2
Block:
Created by miner # 3
Id: 3
Timestamp: 1637995160918
Magic number: -4429177738817892095
Hash of the previous block:
0ff1a96574cd8cf9db8c91eeb436df8efd084582251c081409e43e0f17069d51
Hash of the block:
007577aca398b8fa711229b95f2abb0f959aa73fbaa8939516ca1bea11a467fa
Block data: no messages
Block was generating for 0 seconds
N was increased to 3
Block:
Created by miner # 5
Id: 4
Timestamp: 1637995160932
Magic number: 2352460595297940125
Hash of the previous block:
007577aca398b8fa711229b95f2abb0f959aa73fbaa8939516ca1bea11a467fa
Hash of the block:
00053d5c5b0e958f828c12ae74469fdce1e840334cfa4a431504239133c7c612
Block data:
9 Evelio: How are you?
Block was generating for 0 seconds
N was increased to 4
Block:
Created by miner # 5
Id: 5
Timestamp: 1637995160951
Magic number: 3338207044781263189
Hash of the previous block:
00053d5c5b0e958f828c12ae74469fdce1e840334cfa4a431504239133c7c612
Hash of the block:
000093d155de9a54e2143b97d752b7d57031056ec6eb07b9672c5c0815fd9272
Block data:
9 Armando: This chat is garbage
10 Charles: Interesting...
11 Aramys: Will I ever make decent money?
Block was generating for 0 seconds
N was increased to 5
[1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 10, 11]
編輯:問題是我沒有考慮 currentBlock 中保存的 DataEntry(訊息)。這解決了這個問題:
public long nextMessageId() {
return blocks.stream()
.mapToLong(block -> block.getData().size())
.sum() currentBlock.getData().size() messageBuffer.size() 1L;
}
uj5u.com熱心網友回復:
從你的評論:
nextMessageId() 統計每個塊中集合的大小
下一個訊息 ID:
public long nextMessageId() {
return blocks.stream()
.mapToLong(block -> block.getData().size())
.sum() messageBuffer.size() 1L;
}
你不是也增加了一個額外的messagebuffer尺寸嗎?
在您的createBlock方法中,您將清除此緩沖區。所以ID又變小了。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/371847.html
