[英]How to periodically print to terminal from an if statement that is nested in a while loop (Java)
我正在編寫一個 java 應用程序,它將重復散列一系列輸入值,直到滿足條件。 我通過在 while 循環中嵌套一系列 if/else 語句來實現這一點。 我希望能夠在應用程序主動散列時每 3 秒將散列率打印到終端,並且在滿足條件之前不會重復打印。 我曾嘗試使用 ExecutorService 並安排 TimerTask 但都沒有按照我希望的方式工作,因為在滿足應該停止它們的條件之后它們都繼續執行。 我知道我錯過了一些東西,但我不知道是什么):
我已經包含了一個小片段,請隨時詢問您認為相關的任何信息。
任何幫助將不勝感激!
我嘗試使用這樣的 TimerTask:
while(iterator) {
if (difficulty == 1) {
if (!hash.startsWith("0")) {
long updatedTime = System.nanoTime();
Nonce++;
long deltaN = updatedTime - startTime;
long deltaS = (deltaN / 1000000000);
long hashRate = (Nonce / deltaS);
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println("Current hash rate: " + hashRate + " " + "hash/s");
}
}, 0, 3000);
} else {
System.out.println("Valid hash found! " + hash);
iterator = false;
}
}
}
編輯:完成后這基本上是一個俗氣的“區塊鏈”,我將用作說明目的作為教學工具,考慮到這一點,我已經包括了下面的“礦工”方法的其余部分:
public void miner(long index, long currentTimeMillis, long data, long Nonce, String previousBlockHash, int difficulty) throws InterruptedException {
this.index = index;
this.currentTimeMillis = currentTimeMillis;
this.pszTimeStamp = pszTimeStamp;
this.Nonce = Nonce;
this.previousBlockHash = previousBlockHash;
this.difficulty = difficulty;
this.data = data;
boolean iterator = true;
String blockHeader = (index + currentTimeMillis + data + Nonce + previousBlockHash + difficulty);
String hash = SHA256.generateHash(blockHeader);
long startTime = System.nanoTime();
TimeUnit.SECONDS.sleep(2);
while (iterator) {
blockHeader = (index + currentTimeMillis + data + Nonce + previousBlockHash + difficulty);
hash = SHA256.generateHash(blockHeader);
if (difficulty == 1) {
if (!hash.startsWith("0")) {
long updatedTime = System.nanoTime();
Nonce++;
long deltaN = updatedTime - startTime;
long deltaS = (deltaN / 1000000000);
long hashRate = (Nonce / deltaS);
System.out.println("Current hash rate: " + hashRate
} else {
System.out.println("\n");
System.out.println("Hash found! \n");
System.out.println("Mined block hash: \n" + hash);
}
} else if (difficulty == 2) {
...........
'miner' 方法采用的所有參數都由包含 main 函數的啟動類傳遞給它。 我的目標是能夠在每隔幾秒搜索“有效”哈希時打印哈希率,而不是每秒打印數千次。
我有幾點建議:
我個人更喜歡在while(true)
循環中使用break
while(true)
不是循環變量。 我覺得它使代碼更具可讀性;
您正在循環內重新聲明Timer
,這意味着每次循環迭代都會創建一個新計時器。 您需要在循環之外創建一次計時器。
Timer
變量需要是最終的,以允許您在 TimerTask 的運行函數中調用timer.cancel()
。 如果您計划在 run 函數之外終止計時器,則Timer
變量不必是最終的。
import java.util.*;
public class Test{
static double Nonce;
public static void main(String... args) throws Exception{
final Timer timer = new Timer();
timer.schedule(new TimerTask(){
public void run(){
//calcualte hashRate by any formula
double hashRate = Nonce/100.0;
//check if the timer needs to continue, else call timer.cancel()
System.out.println(hashRate);
}
}, 0, 500);
while(true){
Thread.sleep(100);
Nonce++;
if(Nonce == 100){
timer.cancel(); //or terminate the timer outside the loop
break;
}
}
}
}
如果您需要任何幫助,請告訴我。
編輯:
我注意到了一些事情:
類變量Nonce
不能是靜態的,否則它將在類的所有實例之間共享。
變量名在函數聲明中不能是Nonce
,否則無論何時在miner函數中使用Nonce
都會使用本地副本。
如果不直接計算 hashRate,則 deltaS 可能為零,這可能會導致除以 0 的錯誤。
如果您需要任何說明,請告訴我。
public class ChainBuilder extends MainChain {
private long index;
private long currentTimeMillis;
private long data;
private int difficulty;
private String pszTimeStamp;
private String previousBlockHash;
private String currentHash;
private String genesisHash;
public long Nonce; //Nonce cannot be be static, otherwise it will cause issues if more than one object is created.
public static long startTime;
.......
public void miner(long index, long currentTimeMillis, long data, long _Nonce /*You cannot use Nonce here*/, String previousBlockHash, int difficulty) throws InterruptedException {
this.index = index;
this.currentTimeMillis = currentTimeMillis;
this.pszTimeStamp = pszTimeStamp;
this.Nonce = _Nonce; /*In this scope, Nonce refers to the local variable, and this.Nonce refers to the class variable.
If you use Nonce in this scope, then the class variable will not be changed.*/
this.previousBlockHash = previousBlockHash;
this.difficulty = difficulty;
this.data = data;
boolean iterator = true;
String blockHeader = (index + currentTimeMillis + data + Nonce + previousBlockHash + difficulty);
String hash = SHA256.generateHash(blockHeader);
startTime = System.nanoTime();
TimeUnit.SECONDS.sleep(2);
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
long endTime = System.nanoTime();
long deltaN = endTime - startTime;
//long deltaS = (deltaN / 1_000_000_000);
long hashRate = (1_000_000_000 * Nonce / deltaN); /*calculate the hashRate directly, because if deltaN < 1_000_000_000,
then deltaS will be 0, giving a divide by zero error.*/
System.out.println("Current hash rate: " + hashRate + " " + "hash/s");
}
}, 0, 3000);
while (iterator) {
blockHeader = (index + currentTimeMillis + data + Nonce + previousBlockHash + difficulty);
hash = SHA256.generateHash(blockHeader);
if (difficulty == 1) {
if (!hash.startsWith("0")) {
Nonce++;
} else {
System.out.println("Hash found!");
timer.cancel();
.......
好的,所以對我有用的是將相關變量聲明為靜態,將計時器的開始置於循環之前,並在發現有效散列時取消,如下所示:
public class ChainBuilder extends MainChain {
private long index;
private long currentTimeMillis;
private long data;
private int difficulty;
private String pszTimeStamp;
private String previousBlockHash;
private String currentHash;
private String genesisHash;
public static long deltaS;
public static long deltaN;
public static long Nonce;
public static long startTime;
public static long endTime;
public static long hashRate;
.......
public void miner(long index, long currentTimeMillis, long data, long Nonce, String previousBlockHash, int difficulty) throws InterruptedException {
this.index = index;
this.currentTimeMillis = currentTimeMillis;
this.pszTimeStamp = pszTimeStamp;
this.Nonce = Nonce;
this.previousBlockHash = previousBlockHash;
this.difficulty = difficulty;
this.data = data;
boolean iterator = true;
String blockHeader = (index + currentTimeMillis + data + Nonce + previousBlockHash + difficulty);
String hash = SHA256.generateHash(blockHeader);
startTime = System.nanoTime();
TimeUnit.SECONDS.sleep(2);
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println("Current hash rate: " + hashRate + " " + "hash/s");
}
}, 0, 3000);
while (iterator) {
blockHeader = (index + currentTimeMillis + data + Nonce + previousBlockHash + difficulty);
hash = SHA256.generateHash(blockHeader);
if (difficulty == 1) {
if (!hash.startsWith("0")) {
endTime = System.nanoTime();
Nonce++;
deltaN = endTime - startTime;
deltaS = (deltaN / 1000000000);
hashRate = (Nonce / deltaS);
} else {
System.out.println("Hash found!");
timer.cancel();
.......
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.