多线程返回值



我正在使用Sockets进行Java项目。由于套接字方法是阻塞方法,我不得不制作一个多线程应用程序。

到目前为止,我能够读取来自其他应用程序的传入字节。我将它们写入StringBuilder。我的问题是如何将这个字符串返回到我的主线程。我在想一个类似事件的东西,只要套接字线程读完,我就可以调用它。

我很乐意有任何想法。

public class SocketRunnable implements Runnable {
private final Socket _socket;

public SocketRunnable(Socket socket){
    this._socket = socket;
}
@Override
public void run() {
    StringBuilder sb = new StringBuilder();
    try {
        BufferedReader bufferedReader = 
                new BufferedReader(
                    new InputStreamReader(
                        this._socket.getInputStream()));

    char[] buffer = new char[100];
    int amountOfBytes = bufferedReader.read(buffer, 0, 100); // blocks until the message is received.
    String message  = new String(buffer, 0, amountOfBytes);
    sb.append(message);
    } catch (IOException ex) {
        Logger.getLogger(SocketRunnable.class.getName()).log(Level.SEVERE, null, ex);
    }
    finally{
        // Return (!)
    }
}

我的问题是如何将这个字符串返回到我的主线程。

你不能;不是因为任何技术障碍,而是因为它在概念上没有意义。你的主线程已经开始了,你的返回值有意义的上下文已经丢失了。

所以,要么:

  • 您的主线程必须阻塞才能接收结果(但是多线程有什么意义);

  • 您的主线程已经以面向事件的方式从头开始设计,并且有一个外部事件循环,它将事件从队列中取出并处理它们(如果您正在构建GUI应用程序,这是真的)。

更有意义的是将结果提供给其他代码。这一切都可能发生在同一个线程中,即进行接收的线程。您可以通过简单地调用一个适当的方法来实现这一点。因此,在设计中要解决的问题是,如何使具有该方法的实例可用于在读取线程中执行的代码。

您可以将Callable接口与Executors结合使用。你可以在这里阅读:

可调用:

http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Callable.html

执行程序:

http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Executors.html

只需使用SocketRunnable类实现可调用接口(有一个方法call(),它将在完成后将值从一个线程返回到另一个线程)。

要将结果显示到Swing TextField中,您可以处理结果,一旦您有了字符串,只需执行:

final String msg=???; // Insert your string here
SwingUtilities.invokeLater(new Runnable() {
    public void run() {
        textBox.setText(msg);
    } 
});

invokeLater调用将把您放到正确的线程上,以修改文本字段的内容。

在阻塞队列中写入结果String,并让该队列中的主线程polltake

最新更新