I'm writing a Java program in which I read a line from Console, and do some processing around it. The processing might take 1-2 seconds (ie takes longer than the input rate), while I might keep receiving 50 lines per second.
Although there were some similar questions, they were addressing C/C++ and not Java. So my fundamental question is below:
While still processing an input/line, am I blocked from receiving new inputs? Or somehow they are queued in the system/JVM? Or better ask this way: Do I miss any lines while processing takes time? I don't want to miss any lines by any means.
Here is my code snippet:
Scanner sc = new Scanner(System.in);
while(sc.hasNext()){
//process line. Can take 1-2 seconds.
processInput(sc.nextLine());
}
sc.close();
UPDATE:
As suggested, I came up with making my code more thread-friendly, using Executors
:
ExecutorService executorService = Executors.newFixedThreadPool(10);
while (sc.hasNext()) {
executorService.submit(new Runnable() {
public void run() {
processInput(sc.nextLine());
}
});
}
Just compare these two samples:
Frist, linear without multiple threads:
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();
}
}
}
Then, using a new thread for every input processing:
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();
}
}
Just try it. In both cases you don't miss input, but the difference is that without new threads the processing time adds up (of course) - it doesn't run parallel.
It is blocking, although the documentation could have been clearer: It keeps saying "A scanning operation may block waiting for input." While it could theoretically throw a NoSuchElementException instead of blocking, it seems to me that this is up to the implementation.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.