奇怪的线程行为

时间:2017-05-30 15:41:35

标签: java multithreading

我试图这样做:问题显示在控制台中。如果在一段时间内用户没有写出答案,则询问下一个问题。如果用户输入答案,则立即询问下一个问题。我的代码:

public class Test {
private boolean stopQuestion;
Thread          scannerThread = new Thread();

public static void main(final String[] args) {
    final Test test = new Test();

    test.scannerThread = new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                String string;
                do {
                    string = test.requestInput(new Thread(new Runnable() {

                        @Override
                        public void run() {
                            try {
                                Thread.sleep(3000);
                            } catch (final InterruptedException e) {
                            }
                            test.scannerThread.interrupt();

                        }
                    }));
                } while (!test.stopQuestion);

                System.out.println("Input: " + string);
            } catch (final IOException e) {
                throw new RuntimeException(e);
            }
        }
    });
    test.scannerThread.start();

}

public String requestInput(final Thread timer) throws IOException {
    final BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

    timer.start();

    System.out.println("Any question");
    System.out.println("Please type your answer: ");
    try {
        while (!br.ready()) {
            Thread.sleep(100);
        }
    } catch (final InterruptedException e) {
        System.out.println("Time is over. Next question: ");
        return null;
    }
    System.out.println("Thank You for providing input!");
    return br.readLine();
}

}

如果你没有向控制台写任何内容,一切似乎都按预期工作。时间结束,问下一个问题。但是如果向控制台写入了某些内容,则计时器开始出现故障,下一个问题不会等待指定的时间,有时它根本不会等待。我不明白这件事是什么。

我在方法外部创建了线程实例,并将实例作为引用传递给方法,但随后抛出了IllegalThreadStateException。

1 个答案:

答案 0 :(得分:0)

我发现您的代码存在两个主要问题:

  1. 您正在不断创建应该读取输入的线程:

                do {
                    string = test.requestInput(new Thread(new Runnable() {
    
                        @Override
                        public void run() {
                            try {
                                Thread.sleep(3000);
                            } catch (final InterruptedException e) {
                                e.printStackTrace();
                            }
                            test.scannerThread.interrupt();
    
                        }
                    }));
                } while (!test.stopQuestion); // <-- this is always true
    
  2. 您要在BufferedReader上打开尽可能多的System.in个正在启动的计时器线程:

    final BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    
  3. 此外,您没有关闭任何BufferedReader个实例。

相关问题