2013-12-09 63 views
2

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

截至目前,我能够从其他应用程序读取传入字节。我把它们写入一个StringBuilder。我的问题是如何将这个字符串返回到我的主线程。我正在考虑类似事件的事情,只要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

为什么你需要将它返回到你的主线程?你需要做什么这个返回的字符串? –

+0

我想让它在文本框中可见。所以我想把这个字符串返回给处理这个人的mainThread。 –

+0

如果您在Swing上,则使用EventQueue.invokeLater将事件发布到Event-Dispatch Thread。但我怀疑你的问题在于切换线程:它正在从外部线程访问适当的对象。 –

回答

3

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

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

所以,要么:

  • 你的主线程必须阻止接收结果(但什么是多线程随后的点);

  • 你的主线程已经从面向事件的方式的基础上设计的,并具有外事件循环这需要事件掀起了队列和处理它们(这一点,如果你正在建设一个GUI应用程序是真实的)。

什么更有意义是使结果可用其他一些代码。它可以发生在同一个线程中,即接收到的线程。您只需调用适当的方法即可实现此目的。所以,在你的设计中要解决的问题是,如何使一个实例具有该方法在读线程中执行的代码。

+0

+1我假设他会从主线程中进行轮询。所以在'SocketRunnable'上使用volatile字段可能就足够了。 – Gray

+0

我正在使用MVC模式,并且我的Socket-Thread在模型类中工作。直到现在,整个主线程都是基于事件的,但我并不熟悉外部事件循环。也许我已经在实施这个,但没有意识到。也许SwingWorker是更好的方式去? –

+0

是的,你可以使用'SwingWorker'作为异步任务,这将很好地照顾样板问题。 –

0

将结果字符串写入阻塞队列,并让该线程的主线程polltake

1

显示结果为一个Swing文本字段您可以处理结果,一旦你的字符串只是做:

final String msg=???; // Insert your string here 

SwingUtilities.invokeLater(new Runnable() { 
    public void run() { 
     textBox.setText(msg); 
    } 
}); 

的invokeLater的通话将让你在正确的线程修改文本内容领域。