Java 奇怪的线程行为
我正在尝试这样做:问题显示在控制台中。如果在一段时间内用户没有写出答案,则会询问下一个问题。如果用户输入答案,将立即询问下一个问题。我的代码:Java 奇怪的线程行为,java,multithreading,Java,Multithreading,我正在尝试这样做:问题显示在控制台中。如果在一段时间内用户没有写出答案,则会询问下一个问题。如果用户输入答案,将立即询问下一个问题。我的代码: public class Test { private boolean stopQuestion; Thread scannerThread = new Thread(); public static void main(final String[] args) { final Test test = new Test();
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。我发现您的代码存在两个主要问题:
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
此外,您没有关闭任何这些
BufferedReader
实例。这里似乎有一些错误,但突出的两个主要问题是stopQuestion
的可见性以及从多个线程访问System.in
的整个想法。哦,而且sleep()
也不能用于精确计时,绝对没有任何保证。此外,如果用户键入了一半答案,然后您打印了另一个问题,那么键入的文本仍然存在于输入缓冲区中,这将非常混乱。你的前提是有缺陷的,即你试图做的是不使用控制台程序。我刚刚注意到你使用interrupt()
进行重复的信号发送,这听起来也不是一个好主意。如果你关闭BufferedReader
,你就关闭了系统,并防止以后读取所有输入。不要关闭包裹在系统中的读卡器/扫描仪/输入流。
中应该只有一个BufferedReader
实例,并且最终应该关闭它。永远不要关闭它System.in
由Java运行时管理,应用程序不应关闭它。有关于它的源代码吗?我查找了一些源代码,在应用程序终止之前关闭BufferedReader
似乎是一个好主意。如果您直接从System.in
读取,即未包装,您是否还会在程序末尾添加System.in.close()
?很可能不会,因为你没有打开它。那么,为什么您认为关闭系统是一个“好主意”
仅仅因为您将其包装在帮助程序中,使其更易于阅读文本?你“好主意”的来源是什么?
final BufferedReader br = new BufferedReader(new InputStreamReader(System.in));