java - 线程在java中的服务器客户端中存在多长时间?
问题描述
我有这个简单的服务器-客户端示例:
FooServer.java
:
public class FooServer {
private Socket clientSocket;
public class ClientHandler implements Runnable {
private BufferedReader reader;
private PrintWriter writer;
public ClientHandler(Socket socket) {
try {
reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void run() {
String message;
System.out.println("start of server run()");
try {
writer = new PrintWriter(clientSocket.getOutputStream());
while ((message = reader.readLine()) != null) {
System.out.println("inside of server loop - get new message");
writer.println(message);
writer.flush();
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("end of server run()");
}
}
public void go() {
try {
ServerSocket serverSocket = new ServerSocket(5000);
while (true) {
clientSocket = serverSocket.accept();
Thread watchIncome = new Thread(new ClientHandler(clientSocket));
watchIncome.start();
System.out.println("got connection");
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
new FooServer().go();
}
}
和FooClient.java
:
public class FooClient {
private BufferedReader reader;
private PrintWriter writer;
private Socket socket;
public class ReadIncome implements Runnable {
@Override
public void run() {
System.out.println("start of client run()");
String mes;
try {
while ((mes = reader.readLine()) != null) {
System.out.println("inside of client loop");
System.out.println(mes);
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("end of client run()");
}
}
public void go(String writeOut) {
try {
socket = new Socket("127.0.0.1", 5000);
reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
writer = new PrintWriter(socket.getOutputStream());
} catch (Exception e) {
e.printStackTrace();
}
//--------HERE-----------
//how long will this thread live?
Thread readerThread = new Thread(new ReadIncome());
readerThread.start();
writer.println(writeOut);
writer.flush();
}
public static void main(String[] args) {
FooClient foo = new FooClient();
foo.go("dummy text");
}
}
我运行 FooServer.java,它又产生新的watchIncome
(正在寻找来自客户端的消息的线程while ((message = reader.readLine()) != null)
)。但是在服务器中,它是while(true)
无限循环的,所以它不断地产生新的线程来寻找传入的消息。
但是,在客户端,没有这样的无限循环。据我所知,Java 中的线程,一个线程运行该run()
方法并且......它完成了。线程已死(即不能“重置”以再次运行)。而且由于客户端不会产生新线程(与服务器不同,没有无限循环),客户端不应该“等待”来自服务器的响应,因为线程应该已经死了(这就是我理解java中的线程的方式 -只需运行一次run()
该方法)。
但是相反,客户端将挂在run()
方法的中间 -> 它只会打印inside of client loop
,并且永远不会完成。但这怎么可能,因为线程应该死了?一次readerThread.start();
,在方法内部,该语句while ((mes = reader.readLine()) != null)
将评估为 false(字符串没有任何内容,因此为空),并且方法完成,不应该等待服务器响应(因为我假设线程立即启动)。
而且 - 即使该语句确实评估为真(例如,服务器首先启动,所以客户端在它启动时就得到响应),客户端将 - 再次挂在客户端循环内部,在中间的run()
,但它不应该,因为没有循环,所以它应该继续到方法的末尾(因此到线程的末尾)。最后,我必须终止服务器进程(这是有道理的,因为我从不关闭服务器套接字),但是这样,客户端进程也将结束。但它应该已经死了。有人可以解释一下,为什么客户“等待”,但不应该?
解决方案
推荐阅读
- python - ModuleNotFoundError:没有名为“pythoncom”的模块
- php - 如何为我的包含短博客的网站创建 Twitter 分享链接
- reactjs - React hooks useEffect fetch CORS 问题
- postgresql - 错误:在加载备份时,编码“WIN1252”中字节序列为 0x9d 的字符在编码“UTF8”中没有等效项
- android - 如何使用数据绑定从视图模型调用活动类型扩展函数?
- python - 为什么输出数据一直在变化
- amazon-web-services - 将 Sonarqube 与 AWS Codebuild 连接时出现 SSL 连接问题
- java - org.openqa.selenium.chromium.ChromiumOptions 类型无法解析。请找到附件
- flutter - 颤动中的水平日期选择器
- r - R中的多轴重叠绘图(问题)