如何在一个新线程中运行每次迭代,

发布于 2025-01-21 21:04:11 字数 4403 浏览 7 评论 0原文

我在代码中的循环中有这个,

while(!this.hash.substring(0, difficulty).equals(offset)) {
    this.nonce++;
    this.hash = this.generateHash();
}

我需要在新线程中循环时运行所有迭代,并使整体任务更快!

我尝试覆盖run() 运行接口的方法,如下所示,

@Override
public void run() {
    while(!this.hash.substring(0, this.difficulty).equals(this.offset)) {
        this.nonce++;
        this.hash = this.generateHash();
    }
}

但它像下面一样运行,

ExecutorService es = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
Runnable c = new Create(this.timestamp, this.transactions, this.previousHash, difficulty, offset)
es.execute(c);
es.shutdown();

但这似乎也无法正常工作!

是否可以?

任何答案都很好!提前致谢!

- 编辑 -

以下是完整的代码,while循环在mineblock()方法中。

public class Block {

    public static final String HASH_FN = "SHA-256";
    public static final String ENCODING = "UTF-8";
    
    private Date timestamp;
    private Transaction transaction;
    private String previousHash = "";
    private String hash;
    private Integer nonce = 0;  //random number, dynamic part

    public Block(Date timestamp, Transaction transaction) {
        super();
        this.timestamp = timestamp;
        this.transaction = transaction;
        hash = generateHash();
    }

    public String generateHash() {
                                                            //0, 1, 2  --> 000000000adf0991111111...64
        String base = this.timestamp + this.previousHash + this.nonce + this.transaction.toString();

        try {
            
            final MessageDigest digest = MessageDigest.getInstance(HASH_FN);
            final byte[] hash = digest.digest(base.getBytes(ENCODING));
            final StringBuilder hexString = new StringBuilder();

            for (int i = 0; i < hash.length; i++) {
                
                final String hex = Integer.toHexString(0xff & hash[i]);
                
                if (hex.length() == 1) {
                    hexString.append('0');
                }
                
                hexString.append(hex);
            }
            
            return hexString.toString();
            
        } catch (Exception ex) {
            throw new RuntimeException("Hash Generation Exception");
        }
    }
    
    //[TODO]
    public void mineBlock(int difficulty) {
        
        String offset = String.join("", Collections.nCopies(difficulty, "0"));  //add leading 0
        
        while(!this.hash.substring(0, difficulty).equals(offset)) {
            this.nonce++;
            this.hash = this.generateHash();
        }
        
        System.out.println("A block mined!, hash " + this.hash);
    }

    public String getPreviousHash() {
        return previousHash;
    }
    
    public void setPreviousHash(String previousHash) {
        this.previousHash = previousHash;
    }

    public String getHash() {
        return hash;
    }
    
    public void setHash(String hash) {
        this.hash = hash;
    }

    @Override
    public String toString() {
        return "Block [timestamp=" + timestamp + ", transaction=" + transaction + ", previousHash="
                + previousHash + ", hash=" + hash + "]";
    }
    
    public void setFakeAmount(int fakeAmount) {
        this.transaction.setAmount(fakeAmount);
    }

}

- 编辑2-

我使用以下方法,因为有共享资源。但是,该方法似乎也无法正常工作!

blockthread.java

public class BlockThread extends Thread {


    private Block block;

    public BlockThread(Block block) {
        this.block = block;
    }

    @Override
    public void run() {
        this.block.countNonce();
        this.block.genNewHash();
    }
}

内部block.java,我添加了以下方法以更新相应的变量。

public synchronized void countNonce() {
    this.nonce++;
}

public synchronized void genNewHash() {
    this.hash = this.generateHash();
}

最后,我这样运行了(我将mineblock()方法带入了另一类,其中blknew Block(...)< code>,并从那里运行它。

while(!blk.hash.substring(0, difficulty).equals(offset)) {
    Create create = new Create(blk);
    create.start();
}

/ 但是,总体方法在预期的多个线程中不起作用!

如果有人能提供帮助,那就太好了!!

I have this while loop in my code,

while(!this.hash.substring(0, difficulty).equals(offset)) {
    this.nonce++;
    this.hash = this.generateHash();
}

I need to run every iteration of this while loop in a new thread and making the overall task faster!!

I tried overriding the run() method of the Runnable interface as follows,

@Override
public void run() {
    while(!this.hash.substring(0, this.difficulty).equals(this.offset)) {
        this.nonce++;
        this.hash = this.generateHash();
    }
}

And running it like below,

ExecutorService es = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
Runnable c = new Create(this.timestamp, this.transactions, this.previousHash, difficulty, offset)
es.execute(c);
es.shutdown();

But this does not seem to be working either!!

Is it possible?

Any answer would be great!! Thanks in advance!

-- EDIT --

Following is the full code and the while loop is inside the mineBlock() method.

public class Block {

    public static final String HASH_FN = "SHA-256";
    public static final String ENCODING = "UTF-8";
    
    private Date timestamp;
    private Transaction transaction;
    private String previousHash = "";
    private String hash;
    private Integer nonce = 0;  //random number, dynamic part

    public Block(Date timestamp, Transaction transaction) {
        super();
        this.timestamp = timestamp;
        this.transaction = transaction;
        hash = generateHash();
    }

    public String generateHash() {
                                                            //0, 1, 2  --> 000000000adf0991111111...64
        String base = this.timestamp + this.previousHash + this.nonce + this.transaction.toString();

        try {
            
            final MessageDigest digest = MessageDigest.getInstance(HASH_FN);
            final byte[] hash = digest.digest(base.getBytes(ENCODING));
            final StringBuilder hexString = new StringBuilder();

            for (int i = 0; i < hash.length; i++) {
                
                final String hex = Integer.toHexString(0xff & hash[i]);
                
                if (hex.length() == 1) {
                    hexString.append('0');
                }
                
                hexString.append(hex);
            }
            
            return hexString.toString();
            
        } catch (Exception ex) {
            throw new RuntimeException("Hash Generation Exception");
        }
    }
    
    //[TODO]
    public void mineBlock(int difficulty) {
        
        String offset = String.join("", Collections.nCopies(difficulty, "0"));  //add leading 0
        
        while(!this.hash.substring(0, difficulty).equals(offset)) {
            this.nonce++;
            this.hash = this.generateHash();
        }
        
        System.out.println("A block mined!, hash " + this.hash);
    }

    public String getPreviousHash() {
        return previousHash;
    }
    
    public void setPreviousHash(String previousHash) {
        this.previousHash = previousHash;
    }

    public String getHash() {
        return hash;
    }
    
    public void setHash(String hash) {
        this.hash = hash;
    }

    @Override
    public String toString() {
        return "Block [timestamp=" + timestamp + ", transaction=" + transaction + ", previousHash="
                + previousHash + ", hash=" + hash + "]";
    }
    
    public void setFakeAmount(int fakeAmount) {
        this.transaction.setAmount(fakeAmount);
    }

}

-- EDIT 2 --

I used the following method since there are sharing resources. But, that method also does not seem to be working!!

BlockThread.java

public class BlockThread extends Thread {


    private Block block;

    public BlockThread(Block block) {
        this.block = block;
    }

    @Override
    public void run() {
        this.block.countNonce();
        this.block.genNewHash();
    }
}

Inside Block.java, I added the following methods to update corresponding variables.

public synchronized void countNonce() {
    this.nonce++;
}

public synchronized void genNewHash() {
    this.hash = this.generateHash();
}

Finally, I ran it like this (I took the mineBlock() method into another class where the blk is initialized with a new Block(...), and ran it from there. The non-parallel way works as expected in this design also.),

while(!blk.hash.substring(0, difficulty).equals(offset)) {
    Create create = new Create(blk);
    create.start();
}

When I'm viewing, nonce seems to be getting updated parallelly. But, the overall method does not work in multiple threads as expected!!

It would be great if anyone could help!!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文