Search code examples
javabufferedreaderreadline

Cancel BufferedReader's readLine()


I've written an endless loop in which I want to send a User Message every 5 seconds. Therefore I wrote a thread which waits for 5 seconds and then sends the Message received by the readLine() Method. If the user doesn't give any input the loop doesn't go on because of the readLine() Method waiting for input. So how can I cancel the readLine() Method?

while (true) {
        new Thread() {
            @Override
            public void run() {
                try {
                    long startTime = System.currentTimeMillis();
                    while ((System.currentTimeMillis() - startTime) < 5000) {
                    }
                    toClient.println(serverMessage);
                    clientMessage = fromClient.readLine();

                    System.out.println(clientName + ": " + clientMessage);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }.start();
        serverMessage = input.readLine();
    }

Solution

  • This looks to be a producer-consumer type problem and I would structure this entirely differently since this fromClient.readLine(); is blocking and thus should be performed within another thread.

    So consider reading the user input in another thread into a data structure, a Queue<String> such as a LinkedBlockingQueue<String>, and then retrieve String elements from the queue in the code above every 5 seconds, or nothing if no elements are held in the queue.

    Something like....

    new Thread(() -> {
        while (true) {
            try {
                blockingQueue.put(input.readLine());
            } catch (InterruptedException | IOException e) {
                e.printStackTrace();
            }
        }
    }).start();
    
     new Thread(() -> {
        try {
            while (true) {
                try {
                    TimeUnit.SECONDS.sleep(5);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                String input = blockingQueue.poll();
                input = input == null ? "" : input;
                toClient.println(input);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    
    }).start();
    

    Side notes: don't call .stop() on a thread as that is a dangerous thing to do. Also avoid extending Thread.