1
import java.util.Scanner;

public class test {
    public static void main(String[] args) {

        Runtime.getRuntime().addShutdownHook(new Thread() {
            public void run() {
                System.out.println("Shutdown.");
            }
        });

        String input ="";
        Scanner in = new Scanner(System.in);

        while(true) {
            System.out.print("> ");
//          if (in.hasNext())
                input = in.nextLine();

            if (input.equalsIgnoreCase(""))
                continue;
        }
    }
}

I have this simple console program and I'm trying to implement Ctrl-C to simply quit. After a search I've had partial success using a shut down hook, however it's not working cleanly.

With the line commented the program seems to loop a number of times before quitting (is this the main thread just looping itself?) and with the comment I get an exception on the next line's attempt to read the input stream.

What's the best way to acheive this?

3
  • 1
    You might want to consider using java's console: download.oracle.com/javase/6/docs/api/java/io/Console.html Commented Feb 26, 2011 at 1:31
  • Also I'm unable to replicate your error with the line uncommented. Commented Feb 26, 2011 at 1:38
  • This code works for me: I hit Ctrl-C and the VM exits after running the shutdown hook. Are you sure you have understood shutdown hooks correctly? They run after the VM has begun shutdown, i.e. after it has received the OS signal generated by pressing Ctrl-C. They are not something you should use to initiate a shutdown; instead they are for cleaning up resources even when your program does not terminate gracefully. Commented Feb 26, 2011 at 4:11

1 Answer 1

3

you need to do do something to stop the loop. add private static volatile boolean running = true; to the class, change while(true) to while(running) then get the shutdown hook to set running=false; and check your results. Volatile will ensure your application still shuts down promptly when run under multiple proccessors and/or cores.

[EDIT]

The issue is that the Scanner is blocking (sorry I missed it the first time) which requires you to interrupt the main thread;

private static Thread mainThread;
public static void main(String[] args)
{
    mainThread = Thread.currentThread();

    Runtime.getRuntime().addShutdownHook(new Thread()
    {
        public void run()
        {
            Test.mainThread.interrupt();
        }
    });
    ... // etc
Sign up to request clarification or add additional context in comments.

3 Comments

I'll clarify that the running variable is a Class variable and does not go in the main method. You should get an error if you try to add a static variable to a method, but just to be sure.
Tried this suggestion. It produces the the same effect I'm afraid.
When the VM is killed by a Ctrl-C you don't need to do anything to terminate the loop. The VM will quite happily terminate with live user threads. In this case, the interrupt is likely to have no effect because the VM is allowed to terminate as soon as the shutdown hooks have completed. 'interrupt' will return immediately, so the VM can terminate immediately and will probably not bother doing a context switch back to 'mainThread'. You've got the right idea about gracefully terminating threads; just don't use shutdown hooks to do it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.