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方法中有一个无限循环.我怎么能避免这种情况?
你的设计中有两个陷阱:
ss.accept() 是一个阻止调用,因此您的UI将冻结,直到有传入连接while(true)在EDT中运行循环.而是执行以下操作:
只要你的
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运行它
| 归档时间: |
|
| 查看次数: |
10469 次 |
| 最近记录: |