簡體   English   中英

如何從嵌套在 while 循環中的 if 語句定期打印到終端(Java)

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM