我正在编写一个Java程序,在该程序中,我从Console读取了一行,并对其进行了一些处理。处理过程可能需要1-2秒(即,比输入速率要长的时间),而我可能会继续保持每秒接收50条线。
尽管存在一些类似的问题,但它们只针对C / C ++,而不是Java。所以我的基本问题如下:
同时仍在处理输入/线路时,我是否被阻止接收新输入?还是它们以某种方式在系统/ JVM中排队?还是最好这样问:在处理过程中我会错过任何行吗?我不想以任何方式错过任何行。
这是我的代码段:
Scanner sc = new Scanner(System.in);
while(sc.hasNext()){
//process line. Can take 1-2 seconds.
processInput(sc.nextLine());
}
sc.close();
更新:
根据建议,我想出了使用Executors
使我的代码对线程更友好的方法:
ExecutorService executorService = Executors.newFixedThreadPool(10);
while (sc.hasNext()) {
executorService.submit(new Runnable() {
public void run() {
processInput(sc.nextLine());
}
});
}
答案 0 :(得分:1)
只需比较这两个示例:
第一个没有多个线程的线性拳头:
public class SampleClass {
public static void main(String[] args) {
SampleClass instance = new SampleClass();
instance.start();
}
private void start() {
Scanner sc = new Scanner(System.in);
String input;
while (!(input = sc.nextLine()).equals("exit")) {
processInput(input);
}
sc.close();
}
private void processInput(String input) {
try {
Thread.sleep(2000);
System.out.println("input: " + input);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
然后,对每个输入处理使用新线程:
public class SampleClass {
public static void main(String[] args) {
SampleClass instance = new SampleClass();
instance.start();
}
private void start() {
Scanner sc = new Scanner(System.in);
String input;
while (!(input = sc.nextLine()).equals("exit")) {
processInput(input);
}
sc.close();
}
private void processInput(String input) {
Thread t = new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(2000);
System.out.println("input: " + input);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
t.start();
}
}
只需尝试一下。在这两种情况下,您都不会错过输入,但是不同之处在于,没有新线程的情况下(当然),处理时间加起来了-它不会并行运行。
答案 1 :(得分:0)
它正在阻止,尽管documentation可能更清楚:它一直在说“扫描操作可能会阻止等待输入。” 虽然理论上它可以引发NoSuchElementException而不是阻止,在我看来,这取决于实现。