Java—如何循环读取InputStream,直到用户输入继续?

Java—如何循环读取InputStream,直到用户输入继续?,java,multithreading,sockets,inputstream,outputstream,Java,Multithreading,Sockets,Inputstream,Outputstream,我有一个多线程的客户机-服务器系统,它来回工作,客户机首先通信,服务器应答 但是,对于两个特定的客户机,我需要他们在用户进行输入之前不断检查输入流中是否有数据 该计划是一个停车场管理系统。当停车场已满(可用空间为0个)且车辆到达入口客户时,系统将形成一个等待准许进入的客户队列。当一辆车离开停车场时,队列中的第一个客户端将被删除并添加到该特定入口客户端的阻塞队列中。我已经为每个入口客户端创建了一个直接输出流。因此,当BlockingQueue不为空时,将从该队列获取数据,并将输出发送到该特定客户端

我有一个多线程的客户机-服务器系统,它来回工作,客户机首先通信,服务器应答

但是,对于两个特定的客户机,我需要他们在用户进行输入之前不断检查输入流中是否有数据

该计划是一个停车场管理系统。当停车场已满(可用空间为0个)且车辆到达入口客户时,系统将形成一个等待准许进入的客户队列。当一辆车离开停车场时,队列中的第一个客户端将被删除并添加到该特定入口客户端的阻塞队列中。我已经为每个入口客户端创建了一个直接输出流。因此,当BlockingQueue不为空时,将从该队列获取数据,并将输出发送到该特定客户端的流

但是,问题是-排队的入口客户端应该自动读取其InputStream并打印数据以授予访问权限,但它会导致错误和崩溃。我认为发生的情况是,当系统首次启动时,客户端被困在等待读取最初不存在的数据,因为它在第一阶段需要某种类型的输入,从而导致错误

我如何解决这个问题,以便客户机在有数据可用的情况下读取和打印输入流(无论它是特定的数据,例如包含单词“queue”),如果用户进行输入,还可以继续

我希望这是有道理的,我尽量把它说清楚

服务器类:

public class Server {

public static void main(String[] args) throws IOException {
    //Create the shared objects in the global scope...
    int groundFloor = 0; //SET TO 0 FOR TESTING
    int firstFloor = 0;
    SharedState SharedStateObject = new SharedState(groundFloor,firstFloor);

    //Sets up the server socket on port 4444
    ServerSocket serverSocket = null;
    try 
    {
        serverSocket = new ServerSocket(4444);
        System.out.println("Car Park Server started." + "\n");
    } 
    catch (IOException e) {
        System.err.println("Could not start server on specified port.");
        System.exit(-1);
    }

    //Got to do this in the correct order with only four clients!
    ServerThread GroundFloorEntrance = new ServerThread(serverSocket.accept(), "GroundFloorEntrance", SharedStateObject);
    ServerThread FirstFloorEntrance = new ServerThread(serverSocket.accept(), "FirstFloorEntrance", SharedStateObject);
    ServerThread GroundFloorExit1 = new ServerThread(serverSocket.accept(), "GroundFloorExit1", SharedStateObject);
    ServerThread GroundFloorExit2 = new ServerThread(serverSocket.accept(), "GroundFloorExit2", SharedStateObject);

    GroundFloorEntrance.start();
    FirstFloorEntrance.start();
    GroundFloorExit1.start();
    GroundFloorExit2.start();
    serverSocket.close();

    //Loop for granting queued clients access
    while(true)
    {
        BlockingQueue<String> queuedGroundAccess = SharedStateObject.getQueuedGround();
        BlockingQueue<String> queuedFirstAccess = SharedStateObject.getQueuedFirst();
        if(!queuedGroundAccess.isEmpty())
        {
            Socket clientSocket = GroundFloorEntrance.clientSocket();
            PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
            try 
            {
                out.println(queuedGroundAccess.take());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        if(!queuedFirstAccess.isEmpty())
        {
            Socket clientSocket = FirstFloorEntrance.clientSocket();
            PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
            try 
            {
                out.println(queuedFirstAccess.take());
            } catch (InterruptedException e) 
            {
                e.printStackTrace();
            }
        }
    }
}
}

}

此循环中存在问题。当您写入
fromServer=in.readLine()时它停止程序的执行,并等待从服务器输入数据

while (true) {
        fromServer = in.readLine();
        if(fromServer != null && fromServer.contains("Queue: "))
        {
            System.out.println(fromServer);
        }

        fromUser = stdIn.readLine();
        if (fromUser != null) {
            out.println(fromUser);
        }
        fromServer = in.readLine();
        System.out.println(fromServer);
    }
你能用它做什么?您应该在另一个线程中从服务器读取数据,以防止在等待数据时阻塞主线程。就像这样:

 new Thread(new MyRunnable(fromServer)).start();
MyRunnable将如下所示:

public class MyRunnable implements Runnable {
    private Scanner scanner;

    public MyRunnable(Scanner scanner) {
        this.scanner = scanner;
    }

    @Override
    public void run() {
        while (true) {
            if (scanner.hasNextLine()) {
                System.out.println(scanner.nextLine());
            }
        }
    }
}

如果您有一些问题,请询问。

“导致错误和崩溃”不是问题描述。
public class MyRunnable implements Runnable {
    private Scanner scanner;

    public MyRunnable(Scanner scanner) {
        this.scanner = scanner;
    }

    @Override
    public void run() {
        while (true) {
            if (scanner.hasNextLine()) {
                System.out.println(scanner.nextLine());
            }
        }
    }
}