gpt4 book ai didi

java - 关于Java中的线程和回调的问题

转载 作者:行者123 更新时间:2023-12-03 01:00:29 25 4
gpt4 key购买 nike

我正在阅读Network Programming in Java by Elliotte在线程一章中,他给出了这段代码作为可以在不同线程中运行的计算的示例

import java.io.*;
import java.security.*;
public class ReturnDigest extends Thread {
private String filename;
private byte[] digest;

public ReturnDigest(String filename) {
this.filename = filename;
}

@Override
public void run() {
try {
FileInputStream in = new FileInputStream(filename);
MessageDigest sha = MessageDigest.getInstance("SHA-256");
DigestInputStream din = new DigestInputStream(in, sha);
while (din.read() != -1) ; // read entire file
din.close();
digest = sha.digest();
} catch (IOException ex) {
System.err.println(ex);
} catch (NoSuchAlgorithmException ex) {
System.err.println(ex);
}
}

public byte[] getDigest() {
return digest;
}
}

为了使用这个线程,他给出了一种他称为新手可能使用的解决方案的方法。

The solution most novices adopt is to make the getter method return a flag value (or perhaps throw an exception) until the result field is set.

他所指的解决方案是:

public static void main(String[] args) {
ReturnDigest[] digests = new ReturnDigest[args.length];
for (int i = 0; i < args.length; i++) {
// Calculate the digest
digests[i] = new ReturnDigest(args[i]);
digests[i].start();
}
for (int i = 0; i < args.length; i++) {
while (true) {
// Now print the result
byte[] digest = digests[i].getDigest();
if (digest != null) {
StringBuilder result = new StringBuilder(args[i]);
result.append(": ");
result.append(DatatypeConverter.printHexBinary(digest));
System.out.println(result);
break;
}
}
}
}

然后,他继续提出一种使用回调的更好方法,他将其描述为:

In fact, there’s a much simpler, more efficient way to handle the problem. The infinite loop that repeatedly polls each ReturnDigest object to see whether it’s finished can be eliminated. The trick is that rather than having the main program repeatedly ask each ReturnDigest thread whether it’s finished (like a five-year-old repeatedly asking, “Are we there yet?” on a long car trip, and almost as annoying), you let the thread tell the main program when it’s finished. It does this by invoking a method in the main class that started it. This is called a callback because the thread calls its creator back when it’s done

他给出的回调方法的代码如下:

import java.io.*;
import java.security.*;
public class CallbackDigest implements Runnable {
private String filename;
public CallbackDigest(String filename) {
this.filename = filename;
}
@Override
public void run() {
try {
FileInputStream in = new FileInputStream(filename);
MessageDigest sha = MessageDigest.getInstance("SHA-256");
DigestInputStream din = new DigestInputStream( in , sha);
while (din.read() != -1); // read entire file
din.close();
byte[] digest = sha.digest();
CallbackDigestUserInterface.receiveDigest(digest, filename); // this is the callback
} catch (IOException ex) {
System.err.println(ex);
} catch (NoSuchAlgorithmException ex) {
System.err.println(ex);
}
}
}

CallbackDigestUserInterface 的实现及其用法如下:

public class CallbackDigestUserInterface {
public static void receiveDigest(byte[] digest, String name) {
StringBuilder result = new StringBuilder(name);
result.append(": ");
result.append(DatatypeConverter.printHexBinary(digest));
System.out.println(result);
}
public static void main(String[] args) {
for (String filename: args) {
// Calculate the digest
CallbackDigest cb = new CallbackDigest(filename);
Thread t = new Thread(cb);
t.start();
}
}
}

但是我的问题(或澄清)是关于他对这种方法所说的话......他提到了

The trick is that rather than having the main program repeatedly ask each ReturnDigest thread whether it’s finished, you let the thread tell the main program when it’s finished

查看代码,为运行单独计算而创建的线程实际上是继续执行原始程序的线程。 它不像将结果传递回主线程。看来它成为了主线程!

所以任务完成时主线程并没有得到通知(而不是主线程轮询)。就是主线程不关心结果。它运行到最后并结束。新线程完成后只会运行另一个计算。

我的理解正确吗?

这如何进行调试?该线程现在成为主线程吗?调试器现在会这样对待它吗?

还有其他方法可以实际上将结果传递回主线程吗?

我将不胜感激任何帮助,这有助于更好地理解这一点:)

最佳答案

认为“主”线程(public static void main 运行的线程)应该被视为应用程序的主线程,这是一种常见的误解。例如,如果您编写一个 GUI 应用程序,则启动线程可能会在程序结束之前完成并终止。

此外,回调通常由它们被移交给的线程调用。这在 Swing 和许多其他地方(例如,包括 DataFetcher )都是如此

关于java - 关于Java中的线程和回调的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58941436/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com