如何阻止 Java 扫描器接受输入
How to stop Java Scanner from accepting input
所以,我正在开发一个从命令行运行的测验程序,测验有时间限制。我想做的是在用户时间结束时立即停止测验,即使他们正在回答问题。我正在使用 Java 的 Scanner 来获取用户的输入,所以我基本上想告诉 Scanner 对象终止,即使它正在接受输入。
现在,我知道我可以在事后追溯惩罚超时的用户,但我只是希望在超过时间限制后终止测验。例如,有没有办法用多线程来做到这一点?
A Java 扫描器正在使用阻塞操作。阻止它是不可能的。甚至不使用 Thread.interrupt();
但是您可以使用 BufferedLineReader
阅读并能够停止线程。这不是一个巧妙的解决方案,因为它需要暂停片刻(否则它会使用 100% CPU),但它确实有效。
public static class ConsoleInputReadTask {
private final AtomicBoolean stop = new AtomicBoolean();
public void stop() {
stop.set(true);
}
public String requestInput() throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.println("ConsoleInputReadTask run() called.");
String input;
do {
System.out.println("Please type something: ");
try {
// wait until we have data to complete a readLine()
while (!br.ready() && !stop.get()) {
Thread.sleep(200);
}
input = br.readLine();
} catch (InterruptedException e) {
System.out.println("ConsoleInputReadTask() cancelled");
return null;
}
} while ("".equals(input));
System.out.println("Thank You for providing input!");
return input;
}
}
public static void main(String[] args) {
final Thread scannerThread = new Thread(new Runnable() {
@Override
public void run() {
try {
String string = new ConsoleInputReadTask().requestInput();
System.out.println("Input: " + string);
}
catch (IOException e) {
throw new RuntimeException(e);
}
}
});
scannerThread.start();
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
scannerThread.interrupt();
}
}).start();
}
我受够了看着人们谈论编程并提供不了解编程的低劣解决方案。最糟糕的是,谈论像 Java™ 这样灵活的语言是。
这是您的解决方案,各位:
public static void main(String[] args) throws IOException
{
Scanner sc = new Scanner(new BufferedInputStream(System.in), "UTF-8");
String item;
while (true)
{
System.out.print("Give me some input:\t");
if (!(item = sc.nextLine()).equals(""))
System.out.println("\nYour Input was:\t" + item);
else
break;
}
System.out.println("Goodbye, see you again!");
}
来自Java™编程大师(手握多年经验)8-|
示例输出:
Give me some input: Your
Your Input was: Your
Give me some input: Programming
Your Input was: Programming
Give me some input: Knowledge
Your Input was: Knowledge
Give me some input: Sucks
Your Input was: Sucks
Give me some input: !!!
Your Input was: !!!
Give me some input: In the next line I'll just type ENTER so that my input is recognized as empty ;-)
Your Input was: In the next line I'll just type ENTER so that my input is recognized as empty ;-)
Give me some input:
Goodbye, see you again!
所以,我正在开发一个从命令行运行的测验程序,测验有时间限制。我想做的是在用户时间结束时立即停止测验,即使他们正在回答问题。我正在使用 Java 的 Scanner 来获取用户的输入,所以我基本上想告诉 Scanner 对象终止,即使它正在接受输入。
现在,我知道我可以在事后追溯惩罚超时的用户,但我只是希望在超过时间限制后终止测验。例如,有没有办法用多线程来做到这一点?
A Java 扫描器正在使用阻塞操作。阻止它是不可能的。甚至不使用 Thread.interrupt();
但是您可以使用 BufferedLineReader
阅读并能够停止线程。这不是一个巧妙的解决方案,因为它需要暂停片刻(否则它会使用 100% CPU),但它确实有效。
public static class ConsoleInputReadTask {
private final AtomicBoolean stop = new AtomicBoolean();
public void stop() {
stop.set(true);
}
public String requestInput() throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.println("ConsoleInputReadTask run() called.");
String input;
do {
System.out.println("Please type something: ");
try {
// wait until we have data to complete a readLine()
while (!br.ready() && !stop.get()) {
Thread.sleep(200);
}
input = br.readLine();
} catch (InterruptedException e) {
System.out.println("ConsoleInputReadTask() cancelled");
return null;
}
} while ("".equals(input));
System.out.println("Thank You for providing input!");
return input;
}
}
public static void main(String[] args) {
final Thread scannerThread = new Thread(new Runnable() {
@Override
public void run() {
try {
String string = new ConsoleInputReadTask().requestInput();
System.out.println("Input: " + string);
}
catch (IOException e) {
throw new RuntimeException(e);
}
}
});
scannerThread.start();
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
scannerThread.interrupt();
}
}).start();
}
我受够了看着人们谈论编程并提供不了解编程的低劣解决方案。最糟糕的是,谈论像 Java™ 这样灵活的语言是。
这是您的解决方案,各位:
public static void main(String[] args) throws IOException
{
Scanner sc = new Scanner(new BufferedInputStream(System.in), "UTF-8");
String item;
while (true)
{
System.out.print("Give me some input:\t");
if (!(item = sc.nextLine()).equals(""))
System.out.println("\nYour Input was:\t" + item);
else
break;
}
System.out.println("Goodbye, see you again!");
}
来自Java™编程大师(手握多年经验)8-|
示例输出:
Give me some input: Your
Your Input was: Your
Give me some input: Programming
Your Input was: Programming
Give me some input: Knowledge
Your Input was: Knowledge
Give me some input: Sucks
Your Input was: Sucks
Give me some input: !!!
Your Input was: !!!
Give me some input: In the next line I'll just type ENTER so that my input is recognized as empty ;-)
Your Input was: In the next line I'll just type ENTER so that my input is recognized as empty ;-)
Give me some input:
Goodbye, see you again!