Java swing GUI冻结

Nic*_*ers 5 java sockets concurrency user-interface swing

我正在使用套接字编写Java客户端/服务器GUI应用程序,这是问题所在:

我有一个按钮开始侦听指定的端口:

按钮actionPerformed方法

private void listenButtonActionPerformed(java.awt.event.ActionEvent evt) {                                             
    int port = Integer.parseInt(portTextfield.getText(), 10);

    try {
        socket.listen(port);
    } catch (IOException ex) {
    }
}
Run Code Online (Sandbox Code Playgroud)

这是socket.listen方法

public static void listen() throws IOException {
    ServerSocket ss = new ServerSocket(port);

    while (true)
        new socket(ss.accept());
}
Run Code Online (Sandbox Code Playgroud)

"socket"类扩展"Thread"
所以在ss.accept()返回一个值后,它会在单独的线程中创建新的socket实例.

单击按钮后,GUI冻结,因为在socket.listen方法中有一个无限循环.我怎么能避免这种情况?

GET*_*Tah 5

你的设计中有两个陷阱:

  1. ss.accept() 是一个阻止调用,因此您的UI将冻结,直到有传入连接
  2. 永远不要while(true)在EDT中运行循环.

而是执行以下操作:

  • 单击该按钮时,创建一个将开始侦听传入连接的线程.
  • 每当有传入连接时,创建另一个将接收传入客户端连接并处理它的线程.


ved*_*ant 5

只要你的

new socket(ss.accept());
Run Code Online (Sandbox Code Playgroud)

立即返回,你只需要改变你的

while (true)
Run Code Online (Sandbox Code Playgroud)

这使得EDT(事件调度线程)进入无限循环,您的GUI变得无法响应.所以,删除这一行.

如果你不能那么使用SwingWorker类(http://docs.oracle.com/javase/7/docs/api/javax/swing/SwingWorker.html#process(java.util.List)创建一个嵌套类范围SwingWorker.只需在listenButtonActionPerformed(java.awt.event.ActionEvent evt)方法中调用swingWoker.execute();(在创建其对象之后).

请参阅教程:http://docs.oracle.com/javase/tutorial/uiswing/concurrency/worker.html

永远不要创建新线程并从Swing EDT运行它