Best way to handle console commands without stalling?

I’m using the LWJGL for a new project, but it’s not for a game, exactly. The point is that this project is meant to take in lines from the console piped from some other device. It’s not important what the other device is, but the point is that a few times a second this device will write a string to the command line, which is then piped into my program.

What’s the best way to handle these string inputs? Provisionally, I am using the scanner, calling “scanner.nextLine()” to read the next line. The problem is that this will pause the program until a new line is written onto the console, which is NOT what I want.

I would rather have the program run as normally, at 60fps or what have you, and IF a new line was written to the console, to THEN call a method using that new string as input.

What is the best way to implement this?

Thanks

I would use a thread which is listening and adding incoming strings to an arraylist and each rendercall I would poll the list from the mainthread.

I didn’t really know about Threads but I took a few hours to research it and made something that works. Thanks!

Oh wait, alls not well. I just realized that even though my window closes when I click “x”, my program keeps running, because in one thread I’m still waiting for scanner.nextLine(). When I type something into the console, the program ends as it should. How do I get my program to end before nextLine() gets what it wants?

Thanks

Make it only check for nextLine while running = true, then before you close the window using the command, change running = false.

I think at least.

EDIT: This will of course require a boolean being added, and adding this to your thread that does the process.
EDIT 2: Apparently you can use interrupts as well. Link below.
http://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html

I do not understand. Here is what the structure of my “reader” looks like, one of the two Runnables being run in it’s own thread.

public class Reader implements Runnable {

	Scanner sc = new Scanner(System.in);
	@Override
	public void run() {
		while(true){
			String input = sc.nextLine();
			MainClass.otherRunnable.pause();
			
			//Until the other thread is done, sleep for a bit and check again...
			while(!MainClass.otherRunnable.hasStopped){
				try {
					Thread.sleep(2);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			
			doSomething(input);
			
			MainClass.otherRunnable.resume();
		}
	}

}

What would you change?

I would make it look like this:

public class Reader implements Runnable {
        boolean mainRunning = true;
	Scanner sc = new Scanner(System.in);
	@Override
	public void run() {
		while(true && mainRunning){
			String input = sc.nextLine();
			MainClass.otherRunnable.pause();
			
			//Until the other thread is done, sleep for a bit and check again...
			while(!MainClass.otherRunnable.hasStopped){
				try {
					Thread.sleep(2);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			
			doSomething(input);
			
			MainClass.otherRunnable.resume();
		}
	}

}

then, when I created the thread, I would pass the running boolean = false from the main thread to it before closing, so that it wouldn’t run it’s while loop, as the main thread would be stopped, so you would never sleep the secondary again. This would look like this:


//on create
Reader reader = new Reader();
//on close
reader.mainRunning = false;
System.exit(0);

*This is highly speculative, I’m no good at threads either. I’m pretty sure it works though.

All I needed to do was insert “System.exit(0)” when I wanted the program to stop. Forgot about that command, thanks!

I’m pointing out the obvious, but just “while(mainRunning)”. The “true &&” bit is redundant.

I don’t know if others would agree, but an endless while loop is a bit of sloppy code. It’s best to terminate your loops gracefully using a boolean flag, as bilznatch has mentioned. Either way… whatever works for you. EDIT: Or does sc.nextLine() block? I see what you’re doing there. Sorry.

Look into Thread.setDaemon(). When you mark a thread as a daemon thread, it will not prevent the JVM from closing when your user thread(s) terminates. It addresses the situation being discussed without having to throw interrupts, juggling booleans, or forcing a JVM exit. Just make sure you call the setDaemon method before starting the thread.

Is that all daemon threads do? I’ve heard about them, but I never looked into them.

Pretty much. Their main purpose is to service user threads, therefore once all of the user threads are dead, they have no reason to stick around and the JVM happily disposes of them. The main caveat to be aware of when using them is that there is no finalization performed by the JVM when it kills a daemon thread so any cleanup code you may have in a “finally” block will never get triggered. This limits their usefulness somewhat, but it presents a straightforward and practical solution for the situation being discussed. :slight_smile:

Alright sweet, thanks for the explanation. That’s why I love this forum, learn a new thing everyday.