#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.