0

I'm trying to understand what is the correct way to implement in java a program that continuously read messages from the console and according to the message it performs different operations.

At the moment I have created two threads one that takes care of reading messages from the console, the other to perform operations, these operations not in all cases must stop reading console input

this is the code of thread1 which is started from the main and then continue in its reading cycle from the console.

public class Thread1 implements Runnable{

    public void run() {
        String input;
        Scanner scanner = new Scanner(System.in);
        while(true){
            System.out.println("Insert command:");
            //edited part
            try {
                input = scanner.nextLine();
            }
            catch (Exception e) {
                // TODO: handle exception
                e.printStackTrace();
                scanner.close();
                break;
            }

            String[] strings = input.split(" ");


            switch (strings[0]) {
            case "something":
                //do something
                break;

                ...


            case "login":
                //something...

                //here I start second thread
                Sender senderTask = new Sender(Thread.currentThread());
                Thread senderThread = new Thread(senderTask);
                senderThread.start();

                break;

                //this thread now does not end but waits for other input messages

            default:
                break;
            }
        }
    }
}

the senderThread performs operations and at some point I don't want thread1 to continue reading console input, it is stuck on scanner.nextLine() waiting for input. So I thought about stopping it using thread.stop() is it correct? is there a better way? this is the senderThread code

public class Sender implements Runnable {
    private Thread thread1;

    public Sender(Thread thread1) {
        this.thread1 = thread1;
    }

    public void run() {
        while(true) {
            //in short here I am waiting for an udp package, if it arrives I don't want to read the messages from the console anymore 
            //so somehow I end thread1 and I have to try to close the scanner, is it right to do it this way?
            //I know stop() is deprecated, is there something else that I can use?
            //edited part
            thread1.interrupt();


            //here I create a new scanner because after I received the udp packet 
            //I want to read a message from the console that is different from those that go to the switch case of thread1

            Scanner scanner = new Scanner(System.in);
            String msg = scanner.nextLine();
            if(msg.equals("y")){
                //do something  
                break;
            }
        }
        if(thread1.isAlive()==false) {
            thread1.start();
        }

    }
}

at the end I start thread1 again which reads messages from the console

JayJona
  • 429
  • 1
  • 7
  • 24

2 Answers2

1

I'm not sure if this answers your entire question, but...

Thread.stop() shouldn't even be in the API. I don't think it does anything (and if it does something, it's wrong), it's just a distraction.

use Thread.interrupt(). It should cause that thread to throw an exception if it's held up in some long-running loop. Catch InterruptedException and return from that thread.

This assumes that the method you are interrupting checks for the interrupted flag (thread.interrupted()). I think all long-running java API methods do this (like Scanner.nextLine(), thread.wait() and anything that reads from a port should), but remember that if you have a loop that is just spinning you should check for the interrupted flag and when you see it, throw an InterruptedException yourself.

Bill K
  • 60,031
  • 14
  • 96
  • 147
  • check the changed parts, I added a try catch block on the scanner.nextLine() and used thread.interrupt() instead of thread.stop() but basically the thread is not interrupted, no exceptions are thrown and the input from console continues to be taken from thread1 rather than from senderThread. so scanner.nextLine() does not check for the interrupted flag? – JayJona Jan 07 '20 at 23:01
  • @james sorry I didn't realize that. Try this answer where they discovered the same thing: https://stackoverflow.com/a/4983156/12943 – Bill K Jan 07 '20 at 23:35
0

If your "other things" operations running in the background, i.e. in another thread, prints to the console, they may break apart the users input of the next command.

That is very undesirable, so the correct way is to change the program from an command-line program to a GUI program, e.g. Swing, so the UI can have separate input and output areas.

Andreas
  • 138,167
  • 8
  • 112
  • 195
  • yes I have something that prints on the console and later I don't know if I will use a gui, for the moment I would like to understand how to implement the correct interruption of the thread that reads messages – JayJona Jan 07 '20 at 23:08