правильный способ постоянно читать сообщения с консоли и делать другие вещи - PullRequest
0 голосов
/ 08 января 2020

Я пытаюсь понять, как правильно реализовать в java программу, которая непрерывно читает сообщения с консоли и в соответствии с сообщением выполняет различные операции.

На данный момент у меня есть создал два потока, один из которых выполняет чтение сообщений из консоли, другой - для выполнения операций, эти операции не во всех случаях должны прекратить чтение ввода с консоли

, это код потока 1, который запускается из основного и затем продолжите цикл чтения с консоли.

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;
            }
        }
    }
}

senderThread выполняет операции, и в какой-то момент я не хочу, чтобы thread1 продолжал читать ввод с консоли, он застрял на scanner.nextLine() в ожидании ввода. Поэтому я подумал о том, чтобы остановить его с помощью thread.stop(), это правильно? Есть ли способ лучше? это код отправителяThread

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();
        }

    }
}

, в конце я снова запускаю thread1, который читает сообщения из консоли

Ответы [ 2 ]

1 голос
/ 08 января 2020

Я не уверен, отвечает ли это на весь ваш вопрос, но ...

Thread.stop () даже не должен быть в API. Я не думаю, что он что-то делает (и если он что-то делает, это неправильно), это просто отвлечение внимания.

использовать Thread.interrupt (). Это должно привести к тому, что этот поток сгенерирует исключение, если он задержан в некотором продолжительном l oop. Перехватите InterruptedException и вернитесь из этого потока.

Предполагается, что прерываемый метод проверяет наличие флага прерывания (thread.interrupted ()). Я думаю, что все долгосрочные java методы API делают это (например, Scanner.nextLine (), thread.wait () и все, что читает из порта, должны), но помните, что если у вас есть al oop, это просто вращение Вы должны проверить наличие прерванного флага и, когда увидите, выбросить InterruptedException самостоятельно.

0 голосов
/ 08 января 2020

Если ваши операции «другие вещи», выполняющиеся в фоновом режиме, то есть в другом потоке, выводятся на консоль, они могут разбить ввод пользователя следующей команды.

То есть очень нежелательно, поэтому правильный способ - изменить программу из командной строки на программу GUI, например Swing, чтобы пользовательский интерфейс мог иметь отдельные области ввода и вывода.

...