在特定时间接收输入
我正在编写一个测试系统,而我想做的就是计算用户在这个问题上花了多少秒。 即我打印问题(标准System.out.println),然后等待5秒,如果在这5秒内用户回答(通过标准输入),我想保留这个值。 如果用户在5秒内没有提供答案,则必须跳过此问题并继续。 问题是 – 我正在通过Scanner对象读取用户的答案,而且像in.nextInt()这样的东西是无法控制的,我想。
我怎么解决这个问题? 这是我没有该function的代码的片段,你能给我一些提示添加什么吗?
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 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."); }
在这种情况下我会使用两个线程。 主线程写出问题,等待答案,并保持得分。 子线程读取标准输入并将答案发送到主线程,可能通过BlockingQueue
。
主线程可以使用阻塞队列上的poll()
方法等待五秒钟以获得答案:
… BlockingQueue 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 answers; ReaderThread(BlockingQueue 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()
调用。