Receive input in specific time

后端 未结 1 1748
伪装坚强ぢ
伪装坚强ぢ 2021-01-21 09:12

I\'m writing a testing system and i all i want to do is to count how many seconds had user spent on this question. i.e. i print question(standard System.out.println), then wait

相关标签:
1条回答
  • 2021-01-21 09:26

    I would use two threads in this case. The main thread writes questions, waits for answers, and keeps score. A child thread reads standard input and sends the answers to the main thread, perhaps via a BlockingQueue.

    The main thread can wait for five seconds for an answer by using the poll() method on the blocking queue:

    …
    BlockingQueue<Integer> answers = new SynchronousQueue();
    Thread t = new ReaderThread(answers);
    t.start();
    for (int i = 0; i < numQuestions; ++i) {
      questions.askQuestion(i);
      System.out.print("Your answer (number): ");
      Integer answer = answers.poll(5, TimeUnit.SECONDS);
      playerIsRight = (answer != null) && questions.checkAnswer(i, answer - 1); 
      …
    }
    t.interrupt();
    

    If this call returns null, the main thread knows that the child thread didn't receive any input during that time, and can update the score appropriately and print the next question.

    The ReaderThread would look something like this:

    class ReaderThread extends Thread {
    
      private final BlockingQueue<Integer> answers;
    
      ReaderThread(BlockingQueue<Integer> answers) { 
        this.answers = answers; 
      }
    
      @Override 
      public void run() {
        Scanner in = new Scanner(System.in);
        while (!Thread.interrupted()) 
          answers.add(in.nextInt());
      }
    
    }
    

    Used on System.in, the Scanner will block until the user presses Enter, so it might happen that the user has entered some text but not yet pressed Enter when the main thread times out and moves on to the next question. The user would have to delete their pending entry and enter a new answer for the new question. I don't know of a clean way around this awkwardness, since there's not a reliable way to interrupt the nextInt() call.

    0 讨论(0)
提交回复
热议问题