gpt4 book ai didi

java - 对象输入流死锁

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

我正在开发一个客户端-服务器应用程序,我的服务器可以接收来自两种类型客户端的连接请求,因此我直接在我的服务器中实例化 ObjectInputStream,以识别客户端类型(客户端或工作人员),然后我有每种类型的客户端都有一个线程。

在初始化线程时,我将在服务器中创建的套接字作为参数传递。 (代码如下)

public class Server {

public int PORT;
private ArrayList<DealWithClient> connectedClients;
private ArrayList<DealWithWorker> connectedWorkers;
private ArrayList<String> types = new ArrayList<>();
private BlockingQueue<Runnable> tasks = new BlockingQueue<>();
private SearchTypes searchTypes;
private ObjectOutputStream out;
private ObjectInputStream in;

public static void main(String[] args) {
new Server(args[0]);
}

public Server(String port) {
this.PORT = Integer.parseInt(port);
startServing();
}

public void startServing() {
connectedClients = new ArrayList<>();
connectedWorkers = new ArrayList<>();
try {
ServerSocket s = new ServerSocket(PORT);
System.out.println("Lançou ServerSocket: " + s);
try {
while (true) {
Socket socket = s.accept();
inscription(socket);
}
} finally {
s.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}

private void inscription(Socket socket) {
try {
out = new ObjectOutputStream(socket.getOutputStream());
in = new ObjectInputStream(socket.getInputStream());

Object obj = in.readObject();
if(obj instanceof String) {
String inscriptionMessage = (String) obj;
System.out.println("Mensagem recebida: " + obj);
if(inscriptionMessage.contains("Inscrição cliente")) {
DealWithClient dwc = new DealWithClient(socket, this);
dwc.start();
addClient(dwc);
out.writeObject(searchTypes);
}
if(inscriptionMessage.contains("Inscrição worker")) {
String[] worker = inscriptionMessage.split(" ");
searchTypes = new SearchTypes(worker[4]);
DealWithWorker dww = new DealWithWorker(socket, this);
dww.start();
addWorker(dww);
}
}
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}

public void addClient(DealWithClient client) {
connectedClients.add(client);
System.out.println("Cliente adicionado! »» " + client.toString());
}

public void addWorker(DealWithWorker worker) {
connectedWorkers.add(worker);
System.out.println("Worker adicionado! »» " + worker.toString());
}

下面的 DealWithClient 代码是我遇到问题的地方,因为我无法到达 System.out.println("BBB"),因为它卡在了 ObjectInputStream 的实例化中。

public class DealWithClient extends Thread{

private Socket socket;
private Server server;
private ObjectInputStream in;
private ObjectOutputStream out;
private Client client;

public DealWithClient(Socket socket, Server server) {
this.server = server;
this.socket = socket;
}

@Override
public void run() {
try {
connectToServer();
} catch (IOException e) {
e.printStackTrace();
}
while(!interrupted()) {
treatClientRequests();
}
}

private void connectToServer() throws IOException {

out = new ObjectOutputStream(socket.getOutputStream());
System.out.println("AAA");

in = new ObjectInputStream(socket.getInputStream());
System.out.println("BBB");
}

我在这里寻找过类似的问题,但我没有找到可以解决我的问题的问题。我的问题是,一旦我在服务器中实例化了 ObjectInput 和 ObjectOutput 流,我就无法在我的线程中再次执行此操作?

谢谢!

最佳答案

您很可能会遇到死锁错误,因为当您尝试从同一套接字获取输入流时,ObjectOutputStream 仍在使用该套接字。在实例化下面的 ObjectInputStream 之前,尝试在 out 上调用 close() 方法。调用 close() 方法将释放资源。

关于java - 对象输入流死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59237912/

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