Time limit for an input inside a loop

Nashid Kamal Jitu :

I want to implement a feature where user need to give a input in fixed time limit. I have gone through this answer.

Time limit for an input

This example works one time. When user not giving input in fixed, programe is terminating. But i'm trying to use it multiple time in a loop. I need to check each time what user giving input. See my InputTimer Class, modified from that post answer.

InputTimer.java

public class InputTimer {
    private String str = "";
    public String responseString = "";
    private BufferedReader in;
    TimerTask task = new TimerTask() {
        public void run() {
            if (str.equals("")) {
                responseString = "";
            }
        }
    };

    public void getInput() throws Exception {
        Timer timer = new Timer();
        timer.schedule(task, 5 * 1000);

        in = new BufferedReader(new InputStreamReader(System.in));
        str = in.readLine();
        timer.cancel();
        responseString = str;
    }
}

I've tried to implement this to another class inside a loop:

for(int i=0; i<5; i++){
    System.out.println("Enter res in 5 sec: ");
    InputTimer inputTimer = new InputTimer();
    try {
        inputTimer.getInput();
    } catch (Exception e) {
        e.printStackTrace();
    }
    String responseString = inputTimer.responseString;
    if(responseString.equals("res")){
        //User typed res
    } else {
        //
    }
}

Problem: According to my logic, if user type res in 5 sec, then responseString value will be res, otherwise it'll be empty value. Here after 5 sec Still waiting for user input.

My requirement: If user type res in 5 sec, Then it will work for //User typed res tasks and go for next iterate. If user type nothing in 5 sec, user cant enter input(user input option will be gone), responseString value will become empty then, else block will execute and then go for next iteraton again.

Please help me to find out this scenario solution.

Here is an another try with Joe C solution. It's working for one time. Check the code:

public class test {
    private static BlockingQueue<String> lines = new LinkedBlockingQueue<>();
    public static String inputTimer() throws InterruptedException {

        return lines.poll(5, TimeUnit.SECONDS);
    }

    public static void main(String[] args) {
        for (int i = 0; i < 5; i++) {
            String tmp = "";
            try {
                System.out.print("Iteration " + i + ": Enter any in 5 sec: ");
                Thread t = new Thread(() -> {
                Scanner s = new Scanner(System.in);
                while (true) {
                    lines.add(s.nextLine());
                }
            });
            t.setDaemon(true); 
            t.start();
                tmp = inputTimer();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("You entered: " + tmp);
        }
    }
}

Output Log:

Iteration 0: Enter any in 5 sec: xx
You entered: xx
Iteration 1: Enter any in 5 sec: xx
You entered: null
Iteration 2: Enter any in 5 sec: xx
You entered: null
Iteration 3: Enter any in 5 sec: xx
You entered: xx
Iteration 4: Enter any in 5 sec: You entered: xx
Joe C :

This can be achieved with an event based model. You will need two threads for this (one of these can be the main thread).

The first thread will accept input from a Scanner and add it to an event queue (in our case, an "event" is simply the string that gets entered):

private BlockingQueue<String> lines = new LinkedBlockingQueue<>();

Start said thread in your main method:

Thread t = new Thread(() -> {
    Scanner s = new Scanner(System.in);
    while (true) {
        lines.add(s.nextLine());
    }
});
t.setDaemon(true); // so that this thread doesn't hang at the end of your program
t.start();

Then, when you want to get the input, you can get it from the queue with a timeout:

return lines.poll(5, TimeUnit.SECONDS);

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=107872&siteId=1