Как я могу перехватить исключение другого потока

#java #multithreading #exception #exception-handling #communication

#java #многопоточность #исключение #Информационные материалы

Вопрос:

Код:

 public void doSomethingOrThrowUncheckedException()
{

    Thread worker = new Thread(new Runnable() {
            public void run() {
                try {
                    myObject.doSomething()
                } catch(CheckedException e) {
                    new UncheckedException ();
                }
            }
        });
    worker.start();
}
  

Объяснение

Я хочу выполнить некоторую работу в другом потоке, который может выдать проверенное исключение.

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

Есть ли механизм, который я могу использовать?

Ответ №1:

Можете ли вы создать Наблюдаемый объект вне потока? Если что-то пойдет не так, поток устанавливает значение для изменения этого Наблюдаемого. Основной код является наблюдателем и реагирует на изменение при вызове прослушивателя свойств.

Ответ №2:

Это зависит от того, что вы подразумеваете под вызывающим, зная, что что-то пошло не так. На ум сразу приходит пара вариантов.

  • Рабочий поток может установить флаг ошибки. Недостатком является то, что вызывающему потоку нужно будет проверить флаг, чтобы знать, что что-то пошло не так. (Также может быть флаг для успешного выполнения; пока ни один из них не установлен, вызывающий поток знает, что рабочий поток все еще работает.

  • Рабочий поток может вызвать метод ошибки. Недостатком является то, что вызов будет выполняться в рабочем потоке. С другой стороны, это дает возможность предпринять позитивные действия. Шаблон Observer может быть полезен здесь (хотя я думаю, что реализация Java ужасна).

Комментарии:

1. Мне просто любопытно, почему реализация шаблона Observer в Java ужасна?

2. @gigadot — Во-первых, Observable — это класс, поэтому, если вашему классу нужно подклассировать что-то помимо Object , вы также не можете сделать это Observable. Во-вторых, интерфейс Observer относится к предгенеричной Java, поэтому данные обратного вызова представляют собой объект, который должен быть приведен к любому классу, который вам действительно нужен, без проверки типа во время компиляции.

3. Спасибо. Я не знал, что Observable является частью Java API. Я бы сделал это без расширения класса Observable. Шаблон Observer — это просто концепция дизайна программирования, поэтому я не вижу причины, по которой это должно быть частью стандартного API. Теперь я могу полностью согласиться с вами.

Ответ №3:

Если, когда рабочий поток успешно завершается, он сообщает об успехе Foo или создает объект, который Foo использует, затем разверните этот механизм, чтобы позволить ему передавать проверенное исключение в Foo, а не передавать исключение потоку, вызывающему метод.

 public void doSomething()
{
    Thread worker = new Thread(new Runnable() {
            public void run() {
                try {
                    result = myObject.doSomething();
                    foo.processResult(result);
                } catch(CheckedException e) {
                    foo.processException(e);
                }
            }
        });
    worker.start();
}

public void doSomething()
{

    Thread worker = new Thread(new Runnable() {
            public void run() {
                try {
                    result = myObject.doSomething();
                    resultQueue.add(result);
                } catch(CheckedException e) {
                    resultQueue.add(e);
                }
            }
        });
    worker.start();
}
  

Если doSomething() ни с чем не взаимодействует после успешного завершения, вам нужно будет следовать одному из других ответов.

Комментарии:

1. К сожалению, это ни с чем не взаимодействует! Но чтение вашего кода дало мне несколько хороших идей для решения других проблем, так что спасибо! ( 1)

Ответ №4:

Возможно, вы также захотите взглянуть на UncaughtExceptionHandler.