嗨,我有一个工作正常的GUI应用程序.我创建了一个套接字服务器当我在程序中创建Server类的新对象时,GUI应用程序停止响应.
这是我的服务器类.如果我做
Server s = new Server();
在我的主应用程序中它停止工作.我应该如何添加它?制作一个新帖子?我试过了
Thread t = new Thread(new Server());
t.start();
但问题仍然存在.拜托,我将非常感谢你的帮助.
package proj4;
import java.net.*;
import java.io.*;
public class Server implements Runnable {
ServerSocket serverSocket = null;
Socket clientSocket = null;
ObjectOutputStream out = null;
ObjectInputStream in = null;
int port;
static int defaultPort = 30000;
boolean isConnected = false;
Thread thread;
DataPacket packet = null;
public Server(int _port) {
try {
serverSocket = new ServerSocket(_port);
serverSocket.setSoTimeout(1000*120); //2 minutes time out
isConnected = true;
System.out.println("server started successfully");
thread = new Thread(this);
thread.setDaemon(true);
//thread.run();
} catch (IOException e) {
System.err.print("Could not listen on port: " + port);
System.exit(1);
}
try {
System.out.println("Waiting for Client");
clientSocket = serverSocket.accept();
System.out.println("Client Connected");
thread.run();
} catch (IOException e) {
System.err.println("Accept failed.");
System.exit(1);
}
try {
out = new ObjectOutputStream(clientSocket.getOutputStream());
System.out.println("output stream created successfully");
} catch (IOException e) {
e.printStackTrace();
}
try {
in = new ObjectInputStream(clientSocket.getInputStream());
System.out.println("input stream created successfully");
} catch (IOException e) {
e.printStackTrace();
}
}
public Server() {
this(defaultPort); //server listens to port 30000 as default
}
public void run() {
System.out.println("Thread running, listening for clients");//debugging purposes
while (isConnected) {
try {
packet = this.getData();
Thread.sleep(0);
} catch(InterruptedException e) {
e.printStackTrace();
}
}
}
public DataPacket getData() {
try {
packet = (DataPacket)in.readObject();
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
return packet;
}
public void sendData(DataPacket dp) {
try {
out.writeObject(dp);
} catch (IOException e) {
e.printStackTrace();
}
try {
out.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
public void closeConnection() throws IOException {
out.close();
in.close();
clientSocket.close();
serverSocket.close();
}
}
解决方法:
您的服务器构造函数可能无限期地阻塞在accept()中.
关于Swing程序的两件事:
>永远不要在Swing事件线程中执行任何长任务,并且,
>永远不要在Swing事件线程之外操作任何Swing对象,除非将使用的方法明确记录为线程安全.
这意味着如果服务器是从Swing事件线程启动的 – 也就是说,如果它是为响应按钮单击等而启动的 – 那么是的,您必须为您的Server对象生成另一个线程.否则,您保证在您的线程退出之前阻止Swing事件线程.
您说即使您为服务器生成另一个线程,您的应用程序仍然停止响应?确保您正在调用Thread.start()而不是run(),否则您将意外地通过在您自己的Thread中运行“new Thread”来阻止自己.
笔记:
>我看到你做了一个Thread.sleep(0);在你的run()循环中.这不能保证做任何事情.如果你有一台CPU机器,这可以公平地实现为无操作,允许同一个线程继续运行.
>您确实希望isConnected是易失性的 – 否则无法保证除了更改它之外的任何线程都不会看到对此变量的更改.
>您没有在任何地方将isConnected设置为false,因此run()将一直运行,直到JVM停止或者该Thread接受RuntimeException.
> It is discouraged在构造函数中启动Threads. (见Java Concurrency In Practice.)
>在使用Thread的run()方法之前,您不希望在ServerSocket上接受它!否则,您的构造函数将阻止等待连接,并且不会将控制权返回给事件线程!
>您的构造函数中包含以下代码:
你的代码是:
thread = new Thread(this);
thread.setDaemon(true);
//thread.run();
当你没有注释掉thread.run()时,你没有开始新的线程!要做到这一点,你需要做thread.start().相反,你在调用构造函数的同一个线程中运行这个新的Thread(它永远不会停止,因为上面的原因#3).现在编写代码的方式,所有IOExceptions都会被记录,但是否则会被吞噬.您可能希望在任何IOException以及closeConnection()中将isConnected设置为false.
标签:java,multithreading,swing
来源: https://codeday.me/bug/20190713/1448680.html