在特定时间接收输入

时间:2010-11-19 19:55:00

标签: java

我正在编写一个测试系统,我想做的就是计算用户在这个问题上花了多少秒。即我打印问题(标准System.out.println),然后等待5秒,如果在这5秒内用户回答(通过标准输入),我想保留此值。

如果用户未在5秒内提供答案,则必须跳过此问题并继续。

问题是我正在通过Scanner对象阅读用户答案,而我认为in.nextInt()之类的东西是无法控制的。

我该如何解决这个问题?这是我没有该功能的代码片段,你能给我一些提示吗?

    public void start() {
    questions.prepareQuestions(numQuestions);
    Scanner in=new Scanner(System.in);
    boolean playerIsRight=false,botIsRight=false;
    int playerScore=0,botScore=0;
    for (int i = 0; i < numQuestions; i++) {
        questions.askQuestion(i);
        System.out.print("Your answer(number): ");
        playerIsRight=questions.checkAnswer(i,in.nextInt()-1); //in.nextInt() contains the answer
        botIsRight=botAnswersCorrectly(i + 1);
        if(playerIsRight){ playerScore++; System.out.println("Correct!");}
        else System.out.println("Incorrect!");
        if(botIsRight) botScore++;
        System.out.print("\n");
    }
    if(botScore>playerScore) System.out.println("Machine won! Hail to the almighty transistors!");
    else if(playerScore>botScore) System.out.println("Human won! Hail to the power of nature!");
    else System.out.println("Tie. No one ever wins. No one finally loses.");
}

1 个答案:

答案 0 :(得分:2)

在这种情况下我会使用两个线程。主线程写出问题,等待答案,并保持得分。子线程读取标准输入并将答案发送到主线程,可能通过BlockingQueue

主线程可以使用阻塞队列上的poll()方法等待五秒钟以获得答案:

…
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();

如果此调用返回null,则主线程知道子线程在此期间没有收到任何输入,并且可以适当地更新分数并打印下一个问题。

ReaderThread看起来像这样:

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());
  }

}

System.in上使用,Scanner会阻止,直到用户按下Enter,因此可能会发生用户输入了一些文字但尚未按下Enter的情况主线程超时并继续下一个问题。用户必须删除其待处理的条目并为新问题输入新的答案。我不知道这个尴尬的方法是否干净,因为没有可靠的方法来中断nextInt()电话。