【问题标题】:ObjectInputStream DeadLockObjectInputStream 死锁
【发布时间】:2019-12-08 17:21:25
【问题描述】:

我正在开发一个客户端-服务器应用程序,我的服务器可以接收来自 2 种类型客户端的连接请求,因此我直接在我的服务器中实例化 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 流,我就不能在我的 Thread 中再次执行此操作了吗?

谢谢!

【问题讨论】:

    标签: java objectinputstream


    【解决方案1】:

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

    【讨论】:

    • 如果我理解正确,你是说在我的班级DealWithClient 上,在方法@​​987654327@ 上,在out 实例化之后调用close() 方法?如果我这样做,我有java.net.SocketException: socket closed..
    • 接下来您可以尝试复制socket 对象并在该复制的套接字上打开一个输入流。
    猜你喜欢
    • 1970-01-01
    • 2018-12-09
    • 1970-01-01
    • 2017-12-27
    • 2014-06-08
    • 2013-11-30
    • 2013-12-25
    • 2015-01-29
    • 2017-03-02
    相关资源
    最近更新 更多