Блокировка BufferedReader: как правильно закрыть BufferedReader

У меня возникла тупиковая ситуация с BufferedReader, который читает из InputStreamReader (который читает из InputStream).

Существует графический интерфейс Swing, который закрывается пользователем. JFrame удаляется, и вызывается метод завершения.

 DppGUI gui = this;
 addWindowListener(new WindowAdapter()
    {
        @Override
        public void windowClosing(WindowEvent windowEvent)
        {
            int choice = Dialogs.displayExitQuestionDialog(gui);
            if (choice == JOptionPane.YES_OPTION)
            {
                _dataReciever.finish();
                dispose();
            }
        }
    });

Метод Finish должен быть запущен, чтобы разорвать цикл while, чтобы в конечном итоге позволить потоку завершиться. Вот метод завершения.

public void finish()
{
    _isRunning = false; // This boolean shall break a while loop.
    _listener = null;
    try
    {
        _processInputStream.close();
        System.out.println("Closed input stream");

        _inputStreamReader.close();
        System.out.println("Closed input stream reader");

        _reader.close();
        System.out.println("Closed reader");
    }
    catch (IOException e)
    {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

Проблема в том, что я не могу понять, как закрыть BufferedReader "снаружи", чтобы строка

while ((line = _reader.readLine()) != null)

пропускается.

Вот поток, который блокируется (он должен завершиться, как только пользователь закроет графический интерфейс).

@Override
public void run()
{
    _isRunning = true;
    CommandManager commandManager = new CommandManager();
    Process process = null;
    try
    {
        process = commandManager.makeCommand(MqttCoammands.MOSQUITTO_SUB,
                "HFC_001", "");
        System.out.println("Mosquitto Sub Command generated.");
        _processInputStream = process.getInputStream();
        _inputStreamReader = new InputStreamReader(_processInputStream);
        _reader = new BufferedReader(_inputStreamReader);

        String line = null;
        while (_isRunning)
        {
            while ((line = _reader.readLine()) != null) // The program deadlocks in this line when the GUI is closed
            {
                String[] splits = line.split(";");
                _parameterList = Arrays.asList(splits);
                System.out.println(_parameterList.toString());
                _listener.get(_parameterList);
            }
        }
        System.out.println("Left the While loop. Preparing end of Thread.");
        _listener = null;
        //            finish();
    }
    catch (IllegalCommandException e1)
    {
        e1.printStackTrace();
    }
    catch (UnsupportedOperatingSystemException e1)
    {
        e1.printStackTrace();
    }
    catch (IOException e1)
    {
        e1.printStackTrace();
    }
}

Чтобы закрыть BufferedReader, я попытался установить для него значение null. Я попытался закрыть BufferedReader, InputStreamReader и InputStream (как вы можете видеть в методе завершения), но ничего не работает, программа по-прежнему блокируется. Кто-нибудь сталкивался с такой же проблемой? Кто-нибудь видит решение?

Заранее спасибо!

Редактировать: я забыл упомянуть, что последний вывод консоли перед взаимоблокировкой

закрытый входной поток

Это происходит из метода финиша. Это означает, что InputStreamReader и BufferedReader не закрываются.


person Paul Erlenmeyer    schedule 21.08.2018    source источник
comment
Прервите поток, выполняющий чтение.   -  person Kayaman    schedule 21.08.2018


Ответы (2)


  1. Когда вы создаете оболочку вокруг входного потока/читателя - выполнение закрытия оболочки делает закрытие обернутого объекта. Так что вам не нужны все эти close вызовы.

  2. Я предлагаю вам остановить процесс, который автоматически закрывает поток, и вы получаете null от reader.readLine.

person Dakshinamurthy Karra    schedule 21.08.2018
comment
1. Я так и думал. Спасибо за информацию. 2. Это сработало! Я помещаю процесс (из которого я получаю InputStream) в поле и использую метод process.destroy(). Он немедленно покидает цикл while и позволяет потоку завершиться. - person Paul Erlenmeyer; 21.08.2018

Заменять

    while (_isRunning)
    {
        while ((line = _reader.readLine()) != null) // The program deadlocks in this line when the GUI is closed
        {

с участием

    while (_isRunning && (line = _reader.readLine()) != null)
    {
person Boris Pavlović    schedule 21.08.2018