java - 如何停止等待用户输入?

标签 java timer java.util.scanner interrupt

我正在构建一个程序来询问乘法,我想设置一个计时器来强制这个人在给定的时间内给出答案:

  1. 如果此人在计时器结束前回答:进行下一次乘法
  2. 如果计时器到达终点,停止等待用户输入:进行下一次乘法

目前情况1可以做,2不行,我在想办法从方法中return;在线程之类的东西中,但我不知道如何

所以我面临一个问题,如果 Scanner 打开,等待输入,如何停止它?我试过将它放在线程中并 interrupt() 它或使用 boolean 作为标志,但它不会停止 Scanner


class Multiplication extends Calcul {    
    Multiplication() {  super((nb1, nb2) -> nb1 * nb2); }   
    @Override
    public String toString() {  return getNb1() + "*" + getNb2(); }
}


abstract class Calcul {

    private int nb1, nb2;
    private boolean valid;
    private boolean inTime = true;
    private boolean answered = false;
    private BiFunction<Integer, Integer, Integer> function;

    Calcul(BiFunction<Integer, Integer, Integer> f) {
        this.nb1 = new Random().nextInt(11);
        this.nb2 = new Random().nextInt(11);
        this.function = f;
    }

    void start() {
        Scanner sc = new Scanner(System.in);
        System.out.println("What much is " + this + " ?");

        Timer timer = new Timer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                if (!answered) {
                    inTime = false;
                }
            }
        }, 5 * 1000);

        int answer = Integer.parseInt(sc.nextLine());
        if (inTime) {
            checkAnswer(answer);
            timer.cancel();
        }
    }    

    private void checkAnswer(int answer) {
        System.out.println("You said " + answer);
        valid = (function.apply(nb1, nb2) == answer) && inTime;
        answered = true;
    }

    int getNb1() {   return nb1;  }    
    int getNb2() {   return nb2;  }    
    boolean isValid() { return valid; }

     public static void main(String[] args) {
         List<Calcul> l = Arrays.asList(new Multiplication(), new Multiplication(), new Multiplication());
         l.forEach(Calcul::start);
}
}

最佳答案

您可以检查 System.in.available() > 0 以查看是否有要读取的行。仅当此返回 true 时调用 sc.nextLine() 以实际接收输入。

一个例子:

Scanner sc = new Scanner(System.in);

long sTime = System.currentTimeMillis();
while (System.currentTimeMillis() - sTime < 5000)
{
    if (System.in.available() > 0)
    {
        System.out.println(sc.nextLine());
    }
}

sc.close();

如果有东西要读,这会从控制台读取 5 秒,然后再次打印出来。 注意:当实际使用它时,您可能会在循环中抛出一个sleep,以免占用太多系统资源。

请注意,这是一个可以工作的解决方案:available() 往往是一种不可靠的方法,它会进行一些估计并且可能出错。我可能不会在时间关键的系统等中依赖它。

还要进一步扩展,这种方法依赖于控制台以大多数控制台的工作方式工作(换句话说:我所知道的所有控制台):仅当用户输入换行符时(通过例如按 enter)该行实际上被提供给 System.in 进行处理。否则 available() 将在仅输入一个字符时返回 true。

关于java - 如何停止等待用户输入?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50154207/

相关文章:

timer - 如何在 tkinter 中给定时间后运行函数?

java - 扫描仪类 ~ hasNextDouble();

java - 带有 3 个 jPanel 的 JFrame.getComponentCount 返回 1

c# - 如何动态设置 system.timer 的名称

java - 为什么 final 变量不能用在 switch 语句中?

c - 如何在linux下用c语言创建定时器?

java - 如何让扫描仪搜索 token ,然后返回其后的 token ?

Java - 使用分隔符分隔不同参数来解析文本

java - 为什么我的代码每次都显示相同的输出?

java - 如何使用git中止特定文件的 merge ?