How to make a while to run until scanner get input?

15,484

Do I need to use multiple threads for this?

Yes.

Since using a Scanner on System.in implies that you're doing blocking IO, one thread will need to be dedicated for the task of reading user input.

Here's a basic example to get you started (I encourage you to look into the java.util.concurrent package for doing these type of things though.):

import java.util.Scanner;

class Test implements Runnable {

    volatile boolean keepRunning = true;

    public void run() {
        System.out.println("Starting to loop.");
        while (keepRunning) {
            System.out.println("Running loop...");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
            }
        }
        System.out.println("Done looping.");
    }

    public static void main(String[] args) {

        Test test = new Test();
        Thread t = new Thread(test);
        t.start();

        Scanner s = new Scanner(System.in);
        while (!s.next().equals("stop"));

        test.keepRunning = false;
        t.interrupt();  // cancel current sleep.
    }
}
Share:
15,484
Xenovoyance
Author by

Xenovoyance

Ten years in the software development industry have taken me from a developer, to a tester, to a writer to an owner. Personally I am interested in design, photography, keeping fit and working the stock market. You can follow me on Twitter (twitter.com/xenovoyance) or using any of my blogs: xds.se (EN) - software development and productivity Digital photo guide (EN) - photography and photo editing PM Karlsson (SE) - stock market and finance Hej, Martin här. (SE) - personal just about anything Strange fact; I have designed a coffee mug a few years ago which is currently being sold in the US.

Updated on June 05, 2022

Comments

  • Xenovoyance
    Xenovoyance almost 2 years

    I'm trying to write a loop which runs until I type a specific text in console where the application is running. Something like:

    while (true) {
    try {
        System.out.println("Waiting for input...");
        Thread.currentThread();
        Thread.sleep(2000);
        if (input_is_equal_to_STOP){ // if user type STOP in terminal
            break;
        }
    } catch (InterruptedException ie) {
        // If this thread was intrrupted by nother thread
    }}
    

    And I want it to write a line each time it pass through so I do not want it to stop within the while and wait for next input. Do I need to use multiple threads for this?

  • Xenovoyance
    Xenovoyance about 13 years
    Ok, thank you! Then I know that I need to look into how to that instead. I did not know that scanner was blocking in that way.
  • corsiKa
    corsiKa about 13 years
    I'm not sure it's 100% accurate to say Scanner blocks, because that gives the impression that Scanner is capable of blocking. Only the things that Scanner wraps are capable of blocking. Because System.in blocks, and Scanner wraps System.in, calls to Scanner.readXYZ() block, but only under the hood. I'm not saying what you have is wrong, I'm merely saying it may be interpreted to imply something that isn't true.
  • aioobe
    aioobe about 13 years
    Yeah.. I realized that too.. Couldn't figure out a better wording. Feel free to rephrase if you have a better suggestion :P
  • corsiKa
    corsiKa about 13 years
    Also, I would add a break to your InterruptedException so you don't immediately get a Running Loop... after you call your t.interrupt(); Still a +1 for an excellent illustration.
  • aioobe
    aioobe about 13 years
    Ah, good point. Since an interrupted exception can be caused by other things, I don't think it's a good idea to break. But I moved the output-line.
  • corsiKa
    corsiKa about 13 years
    I thought about that before I posted the comment, because I couldn't come up with an "easy-enough-for-someone-new-to-scanner-to-understand" explanation either. But, on the chance OP reads the comments, he'll understand how blocking mechanisms apply in the future. If he understands "Scanner blocks" for now, it will work for his current operation (which appears to be a trivial program.)
  • corsiKa
    corsiKa about 13 years
    An option would be catch(InterEx e) { if(!keepRunning) break; } this will cause you to ignore interrupts when you've not canceled operation on the thread, but to break accordingly when you have canceled it.
  • Xenovoyance
    Xenovoyance about 13 years
    I'm here, reading and learning :) Thanks a million for example
  • aioobe
    aioobe about 13 years
    No problem. Welcome to stack overflow by the way :)
  • Xenovoyance
    Xenovoyance about 13 years
    Thanks for the example! CountDownLatch was new for me, I will read up on the usage of it.