Установка флагов между потоками в Java

У меня есть класс, который подключается к серверу, как показано ниже.

@Override
public void run() {
    while (running) {
        try {
            msgHandler.log("Connecting to " + host + ":" + port);
            Socket s = new Socket(host, port);

            if (s.isConnected() && !s.isClosed()) {
                msgHandler.connectionInit(s);
            }
            BufferedInputStream input = new BufferedInputStream(s.getInputStream());

    }
}

Потребитель, который является msgHandler, часто опрашивает сокет, если соединение когда-либо прерывается, как показано ниже.

@Override
public void connectionInit(Socket s) throws IOException {
    logger.info("Connected to AWW Service on " + configuration.getAwwHost() + ":" + configuration.getAwwPort());

    output = new BufferedOutputStream(s.getOutputStream());

    connector.componentReady();
    Timer t = new Timer();
    t.schedule(new TimerTask() {
        @Override
        public void run() {
                try {
                    pollServer();
                } catch (IOException e) {
                    // SOCKET GETS BROKEN HERE 
                }
        }
    }, 0, 25000);

}

Вопрос в том, как я могу связаться с исключением, которое я получаю, когда соединение сокета разрывается обратно в поток run(), чтобы он мог попытаться повторно инициализировать сокет и входной поток?

Я не думаю, что здесь уместны механизмы notify() или wait(), так как wait() просто переводит поток run() в спящий режим. Я подумал, что эквивалентно установке флага, когда соединение разрывается, и поток run() постоянно проверяет флаг, и когда он установлен в значение true, он повторно инициализирует сокет. Но я уверен, что для достижения этого был бы более эффективный многопоточный подход, встроенный в java.


person Saad    schedule 20.07.2016    source источник


Ответы (2)


Я думаю, что самый простой подход — использовать переменная AtomicBoolean, доступная для обоих потоков — при необходимости вы можете передать эту переменную при создании класса запуска каждого потока. Хорошая вещь в AtomicBoolean заключается в том, что он уже является потокобезопасным/синхронизированным и изменчивым, поэтому его можно передавать и изменять по ссылке.

См. этот аналогичный вопрос для более подробной информации.

person Matt Weinecke    schedule 20.07.2016

Я думаю, что в функции run() у вас должен быть код, подобный следующему.

// ...
try
{
    // ...
    int read = input.read(...);
    // ...

}
catch (IOException e)
{
    // TODO: terminate the thread and restart a new connection
}

Таким образом, если во время вызова pollServer() возникает ошибка, мой код выше также должен генерировать исключение.

Также при вызове close функция объекта Socket, вход и выходные потоки будут генерировать относительные исключения.

person sandromark78    schedule 21.07.2016