HTML Diff
0 added 0 removed
Original 2026-01-01
Modified 2026-03-10
1 <p>Теги: java, completablefuture, java.util.concurrent, sleep(3), цепочка асинхронных вызовов, обработка ошибок, exceptionally, futureone.thenacceptbothasync</p>
1 <p>Теги: java, completablefuture, java.util.concurrent, sleep(3), цепочка асинхронных вызовов, обработка ошибок, exceptionally, futureone.thenacceptbothasync</p>
2 <p>У<strong>CompletableFuture</strong>есть ещё интересные функции. Например, надо построить цепочку из асинхронных вызовов. Т.е. после завершения первой асинхронной функции запустить вторую, после второй третью и т.д. В JavaScript для этого применяются<strong>promise</strong>. В Java можно использовать<strong>CompletableFuture</strong>.</p>
2 <p>У<strong>CompletableFuture</strong>есть ещё интересные функции. Например, надо построить цепочку из асинхронных вызовов. Т.е. после завершения первой асинхронной функции запустить вторую, после второй третью и т.д. В JavaScript для этого применяются<strong>promise</strong>. В Java можно использовать<strong>CompletableFuture</strong>.</p>
3 <h2>Выглядит это так:</h2>
3 <h2>Выглядит это так:</h2>
4 private void thenApply() throws ExecutionException, InterruptedException { final CompletableFuture&lt;String&gt; future = CompletableFuture.supplyAsync(()-&gt; { System.out.println("job started"); sleep(3); System.out.println("job done"); return "feature done|"; }).thenApply(result -&gt; { System.out.println("applay result:" + result); return result + " applied"; }); System.out.println("waiting..."); String result = future.get(); System.out.println("finished, result:" + result); }<p>Сначала выполняется первая задача<strong>(sleep(3))</strong>и только после её завершения запустится вторая задача. Причём второй задаче в качестве входного параметра можно передать результаты первой задачи.</p>
4 private void thenApply() throws ExecutionException, InterruptedException { final CompletableFuture&lt;String&gt; future = CompletableFuture.supplyAsync(()-&gt; { System.out.println("job started"); sleep(3); System.out.println("job done"); return "feature done|"; }).thenApply(result -&gt; { System.out.println("applay result:" + result); return result + " applied"; }); System.out.println("waiting..."); String result = future.get(); System.out.println("finished, result:" + result); }<p>Сначала выполняется первая задача<strong>(sleep(3))</strong>и только после её завершения запустится вторая задача. Причём второй задаче в качестве входного параметра можно передать результаты первой задачи.</p>
5 <p>А что делать с ошибками? Как их обрабатывать? У<strong>CompletableFuture</strong>есть встроенный механизм для обработки ошибок, применить его можно так:</p>
5 <p>А что делать с ошибками? Как их обрабатывать? У<strong>CompletableFuture</strong>есть встроенный механизм для обработки ошибок, применить его можно так:</p>
6 private void thenApplyException() throws ExecutionException, InterruptedException { final CompletableFuture&lt;String&gt; future = CompletableFuture.supplyAsync(()-&gt; { System.out.println("job started"); sleep(3); throw new RuntimeException("runTime exception"); }).thenApply(result -&gt; { System.out.println("applay result:" + result); return result + " applied"; }).exceptionally(exception -&gt; { System.out.println("got exception, err:" + exception.getMessage()); return exception.getMessage(); }); System.out.println("waiting..."); String result = future.get(); System.out.println("finished, result:" + result); }<p><em>(*) Обратите внимание на блок<strong>exceptionally</strong>, он запустится, если одна из задач выбросит исключение.</em></p>
6 private void thenApplyException() throws ExecutionException, InterruptedException { final CompletableFuture&lt;String&gt; future = CompletableFuture.supplyAsync(()-&gt; { System.out.println("job started"); sleep(3); throw new RuntimeException("runTime exception"); }).thenApply(result -&gt; { System.out.println("applay result:" + result); return result + " applied"; }).exceptionally(exception -&gt; { System.out.println("got exception, err:" + exception.getMessage()); return exception.getMessage(); }); System.out.println("waiting..."); String result = future.get(); System.out.println("finished, result:" + result); }<p><em>(*) Обратите внимание на блок<strong>exceptionally</strong>, он запустится, если одна из задач выбросит исключение.</em></p>
7 <p>У<strong>CompletableFuture</strong>есть ещё интересная возможность: запускать несколько асинхронных задач, подождать, когда они завершатся и обработать полученные результаты.</p>
7 <p>У<strong>CompletableFuture</strong>есть ещё интересная возможность: запускать несколько асинхронных задач, подождать, когда они завершатся и обработать полученные результаты.</p>
8 <p>Вот пример:</p>
8 <p>Вот пример:</p>
9 private void acceptBoth() { final CompletableFuture&lt;String&gt; futureOne = CompletableFuture.supplyAsync(()-&gt; { System.out.println("job one started"); sleep(3); System.out.println("job one is done"); return "feature done one"; }); final CompletableFuture&lt;String&gt; futureTwo = CompletableFuture.supplyAsync(()-&gt; { System.out.println("job two started"); sleep(7); System.out.println("job two is done"); return "feature done two"; }); System.out.println("waiting..."); futureOne.thenAcceptBothAsync(futureTwo, (result1, result2) -&gt; System.out.println("join:" + result1 + " " + result2)); System.out.println("end"); }<p>Обратите внимание на структуру<strong>futureOne.thenAcceptBothAsync</strong>. Ждём, когда завершатся обе задачи, и обрабатываем итоговый результат. В отличие от предыдущих примеров, в этом фрагменте кода поток выполнения программы не ждёт, когда завершатся<strong>future</strong>, а идёт дальше.</p>
9 private void acceptBoth() { final CompletableFuture&lt;String&gt; futureOne = CompletableFuture.supplyAsync(()-&gt; { System.out.println("job one started"); sleep(3); System.out.println("job one is done"); return "feature done one"; }); final CompletableFuture&lt;String&gt; futureTwo = CompletableFuture.supplyAsync(()-&gt; { System.out.println("job two started"); sleep(7); System.out.println("job two is done"); return "feature done two"; }); System.out.println("waiting..."); futureOne.thenAcceptBothAsync(futureTwo, (result1, result2) -&gt; System.out.println("join:" + result1 + " " + result2)); System.out.println("end"); }<p>Обратите внимание на структуру<strong>futureOne.thenAcceptBothAsync</strong>. Ждём, когда завершатся обе задачи, и обрабатываем итоговый результат. В отличие от предыдущих примеров, в этом фрагменте кода поток выполнения программы не ждёт, когда завершатся<strong>future</strong>, а идёт дальше.</p>
10 <h2>Вывод:</h2>
10 <h2>Вывод:</h2>
11 <p><strong>CompletableFuture</strong>из пакета<strong>java.util.concurrent</strong>предоставляет полезный и простой в использовании функционал, который помогает ускорить разработку и упростить код. В то же время надо помнить, что в<strong>java.util.concurrent</strong>много тонких моментов, требующих понимания и некоторой сноровки в использовании.</p>
11 <p><strong>CompletableFuture</strong>из пакета<strong>java.util.concurrent</strong>предоставляет полезный и простой в использовании функционал, который помогает ускорить разработку и упростить код. В то же время надо помнить, что в<strong>java.util.concurrent</strong>много тонких моментов, требующих понимания и некоторой сноровки в использовании.</p>
12 <p><em>Есть вопрос? Напишите в комментариях!</em></p>
12 <p><em>Есть вопрос? Напишите в комментариях!</em></p>
13  
13