#java #multithreading #exception #concurrency #runnable
#java #многопоточность #исключение #параллелизм #выполняемый
Вопрос:
Итак, я нахожусь в сценарии, где у меня есть метод, который абсолютно ничего не возвращает. (Возвращаемый тип Void). Мне нужно запустить его в другом потоке, хотя. Я знаю, что вы можете создать исключение с помощью callable, но, к сожалению, исключение не будет сгенерировано до тех пор, пока не будет вызван Future.get(), а поскольку он ничего не возвращает, вызов future.get() просто кажется пустой тратой времени. Есть ли более элегантное решение моей проблемы? Вот макет проблемы, с которой я столкнулся:
public static void main(String[] args){
Callable<Void> upStreamer = new Callable<Void>(){
public Void call() throws IOException{
throw new IOException("I want this exception to be thrown!");
}
};
FutureTask<Void> futureTask = new FutureTask<Void>(upStreamer);
Thread uploadThread = new Thread(futureTask);
uploadThread.start();
}
Вот реальная проблема в псевдокоде:
public static void main(String[] args){
new somekindOfThreadLikeThing...
//inside the method
if(criticalCondition == false){
throw new IOException("halt everything and tell the programmer what's wrong.");
}
//Import code that is the part that needs to be multithreaded but the final references will screw it up. (There are inmutable Strings involved. Code will throw uncaught exception if criticalCondition == false. This part will also throw an exception.
}.startOrWhatever();
}
Комментарии:
1. Приведенный выше код — это то, что у вас есть сейчас, или то, к чему вы хотели бы двигаться?
2. Это то, что я пытался сделать с Callable. Из-за особенностей состава моего кода непросто просто вызвать future.get().
3. Кроме того, с точки зрения бесполезного вызова get(), что еще вы хотели бы, чтобы произошло? get() предоставляет точку синхронизации для вашего основного потока, чтобы сказать «ок, теперь я готов посмотреть, как прошла эта фоновая операция». Вы либо получаете значение обратно, либо немедленно получаете ExecutionException, чтобы сообщить вам, что это не удалось — никаких потерь. Единственным другим возможным концептуальным сценарием было бы, чтобы фоновый поток прерывал основной поток в середине того, что он делал, и это, безусловно, было бы менее элегантно. Или, более кратко, то, что только что сказал @SotiriosDelimanolis 🙂
4. Как только
isDone()
возвращает true, вы можете вызватьget()
и знать, что он не заблокируется — если он выдает исключение, перехватите его5. Как насчет CompletableFuture? docs.oracle.com/javase/8/docs/api/java/util/concurrent /…
Ответ №1:
Я решил использовать CompletableFuture. Огромное спасибо ssedano!
http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletableFuture.html