我正在使用套接字处理Java项目。由于Socket方法是阻塞方法,我不得不制作一个多线程应用程序。
截至目前,我能够从其他应用程序读取传入的字节。我把它们写入StringBuilder。我的问题是如何将此字符串返回到我的主线程。我想的是像Event这样的东西,一旦Socket-Thread读完就可以调用它。
我很高兴任何想法。
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 (!)
}
}
答案 0 :(得分:3)
我的问题是如何将此字符串返回给我的主线程。
你不能因为任何技术障碍,而是因为它没有概念意义。你的主要线程已经开始了,你的返回值有意义的上下文就会丢失。
所以,要么:
你的主线程必须阻止接收结果(但那么多线程的重点是什么);
你的主线程已经以面向事件的方式从头开始设计,并且有一个外部事件循环,它将事件从队列中取出并处理它们(如果您正在构建GUI应用程序。)
更有意义的是将结果提供给其他代码。它可以全部发生在同一个线程中,即接收的线程。您只需调用适当的方法即可实现此目的。因此,在您的设计中要解决的问题是,如何使一个具有该方法的实例可用于在读取线程中执行的代码。
答案 1 :(得分:1)
您可以将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()
,它将在完成时将值从一个线程返回到另一个线程。)
答案 2 :(得分:1)
要将结果显示到Swing TextField中,只需执行以下操作即可处理结果:
final String msg=???; // Insert your string here
SwingUtilities.invokeLater(new Runnable() {
public void run() {
textBox.setText(msg);
}
});
invokeLater调用将使您进入正确的线程以修改文本字段的内容。
答案 3 :(得分:0)
将结果字符串写入阻塞队列,并让该队列中的主线程poll
或take
。