首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ObjectInputStream DeadLock

ObjectInputStream DeadLock
EN

Stack Overflow用户
提问于 2019-12-09 01:21:26
回答 1查看 170关注 0票数 0

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

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

代码语言:javascript
复制
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的实例化中。

代码语言:javascript
复制
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流,我就不能在我的线程中再次这样做了?

谢谢!

EN

回答 1

Stack Overflow用户

发布于 2019-12-09 02:07:40

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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59237912

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档