gpt4 book ai didi

java - 调用 LinkedList.add 时线程挂起

转载 作者:行者123 更新时间:2023-12-02 01:15:01 25 4
gpt4 key购买 nike

所以我正在编写两个 ServerSocket。一个监听端口 8085 上的 HTTP 请求并将字节输入保存到静态 LinkedList 中,第二个监听端口 8086 并返回静态 LinkedList 中的所有结果。

问题是,当将数据从 ServerSocket:8085 保存到 LinkedList 时,线程挂起,我不确定为什么。

这是主要的监听器类:

import java.net.ServerSocket;
import java.nio.charset.Charset;
import java.util.*;

public class Listener {

public static LinkedList<byte[]> Calls = new LinkedList<>();

public static void main(String[] args) {
Thread callback = new Thread(new ThreadListener());
callback.start();

while (true) {
try (var listener = new ServerSocket(8086)) {
System.out.println("Listening on 8086...");
try (var client = listener.accept()) {
StringBuffer response = new StringBuffer();
response.append("HTTP/1.1 200 OK\r\n\r\n");
Iterator<byte[]> iterator = Calls.iterator();
while (iterator.hasNext()) {
response.append(new String(iterator.next(), Charset.forName("UTF-8")) + "\r\n");
iterator.remove();
}
client.getOutputStream().write(response.toString().getBytes("UTF-8"));
client.close();
}
} catch (IOException e) {
e.printStackTrace();
}

}


}
}

这是 ThreadListener 类:

import java.io.IOException;
import java.net.ServerSocket;
import java.util.Date;

public class ThreadListener implements Runnable {
@Override
public void run() {
while (true) {
try (var listener = new ServerSocket(8085)) {
System.out.println("Listening on 8085...");
try (var socket = listener.accept()) {
if (!socket.getInetAddress().getHostAddress().equals("127.0.0.1")) {
System.out.println("Not localhost");
} else {
System.out.println("Its us!");
}
Listener.Calls.add(socket.getInputStream().readAllBytes());
System.out.println("Result collected");
Date today = new Date();
String httpResponse = "HTTP/1.1 200 OK\r\n\r\n" + today;
socket.getOutputStream().write(httpResponse.getBytes("UTF-8"));
socket.close();
}

} catch (IOException e) {
e.printStackTrace();
}
}
}
}

就我的测试而言,我尝试调用 127.0.0.1:8085,然后收到 ERR_CONNECTION_RESET,控制台中的内容如下:

Listening on 8085...
Listening on 8086...
Its us!

Process finished with exit code -1 (I killed the app after 2 mins)

事实是“是我们!”消息已打印,但“结果已收集!”就在 LinkedList.add 没有出现之后,我假设 LinkedList.add 是挂起线程的那个。

问候

编辑:没有人调用 8085(或 8086),我正在浏览器上手动执行此操作。我通过创建一个调用方法而不是直接调用 LinkedList.add 解决了同步问题:

    public static synchronized void addElementsToList(byte[] bytes) {
Calls.add(bytes);
}

这确实有效,但调用 8085 套接字每次都会重置连接。

最佳答案

使用浏览器创建请求的测试机制可能也没有帮助,因为 InputStream.readAllBytes()

blocks until all remaining bytes have been read and end of stream is detected, or an exception is thrown. This method does not close the input stream.

来自the documentation 。具体来说,浏览器保持连接打开,因为它期待一些响应。您的服务器正在尝试从连接中读取所有内容直到连接关闭。第 22 条军规(也称为死锁)。

尝试使用 telnet 建立与 localhost:8085 的连接并从客户端关闭连接

telnet 127.0.0.1 8085

^D

其中 ^D 实际上是 [CTRL] 和 [D] 键(例如:注销)

关于java - 调用 LinkedList.add 时线程挂起,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58821488/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com