[英]Searching for alternative to endless loop in Java
我正在做我的家庭作业,这是关于聊天程序。 它有两个接口,一个用于服务器,第二个用于客户端。 程序流程如下:
该程序源自Deitel&Deitel的Java How To Program 6e书。 该示例每个接口只有两个元素:用于显示消息的displayArea(JTextArea)和用于输入消息的输入(JTextField)。
按Enter键会将消息发送到其他人。
Server.java的一段代码如下。 它在无限循环中执行一些重复操作。
public void runServer() {
// set up server to receive connections; process connections
SwingUtilities.invokeLater(new Runnable() {
public void run()
{
try {
// Step 1: Create a ServerSocket.
String portNum = txtPort.getText();
server = new ServerSocket(Integer.parseInt(portNum), 100);
InetAddress ip = InetAddress.getLocalHost();
txtServerIP.setText(ip.getHostAddress());
while (true) {
try {
waitForConnection(); // Step 2: Wait for a connection.
getStreams(); // Step 3: Get input & output streams.
processConnection(); // Step 4: Process connection.
}
// process EOFException when client closes connection
catch (EOFException eofException) {
System.err.println("Client terminated the connection.");
}
finally {
closeConnection(); // Step 5: Close connection.
++counter;
}
} // end while
} // end try
// process problems with I/O
catch (IOException ioException) {
ioException.printStackTrace();
}
}
});
} // end method runServer
它适用于原始代码。 我决定在接口中添加一些GUI元素,并使用Eclipse Luna 4.4.1添加了一个Application窗口。 我添加了IP地址和端口号的输入。 然后我为Server GUI添加了一个“Open Connection”按钮,为Client GUI添加了另一个“Connect to the Server”按钮。
现在我运行Server.java,直到我点击“打开连接”按钮。 然后按钮保持按下,尽管我发布并且表单没有响应。 之后我运行Client.java并连接到服务器并从服务器获取“连接成功”消息。 我发送一些消息后关闭客户端窗口,然后突然所有消息都出现在服务器窗口上。
现在我明白服务器窗口的非响应是因为while ( true )
循环。 换句话说,该程序运行良好,但无法足够快地更新界面。 我想用一个端口监听器来改变它,或者更快或更敏感的其他东西。
我该怎么改变它?
我变了
public void runServer() {
// set up server to receive connections; process connections
SwingUtilities.invokeLater(new Runnable() {...
至
public void runServer() {
// set up server to receive connections; process connections
SwingUtilities.invokeLater(new Thread() {...
但情况仍然不变。
您可以访问我的代码
ServerGUI.java @ http://pastebin.com/pVRi6EfC
ClientGUI.java @ http://pastebin.com/HfftM159
原始代码:
Server.java @ http://pastebin.com/6Q5Z00gb
Client.java @ http://pastebin.com/uCGFGknf
问题是您使用的是SwingUtilities.invokeLater
。 正如这个答案所解释的那样, invokeLater
在应用程序的主Thread
执行run
体。 由于您的UI也在此Thread
运行,因此您需要使用其他方法。
你需要将这个无限循环放在一个Thread中并明确地调用start
这样它就不会阻塞你的UI。
class MyChatServer extends Thread {
public void run() {
// the while loop
}
}
然后,您可以在按下“打开连接”按钮时启动Thread
:
MyChatServer server = new MyChatServer();
server.start();
如果没有显式创建新的Thread
,您的应用程序将只有一个Thread
。 此Thread
将在UI和您需要执行的任何其他工作之间共享。 所以,当你有一些工作(比如你的while(true)
)会占用你唯一的Thread
,你的UI会冻结,直到再次给予控制权。
因此,通过创建新的Thread
,您允许UI保持控制而不是冻结。
您的无限循环是忙碌的等待,这会阻止您的UI刷新。 你有两个问题:
请寻找替代方案 ,而不是忙着等待。
此外,您应该在引擎的不同线程中使用UI。 您可能还想阅读有关swing并发性的内容 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.