{"id":522,"date":"2024-10-05T09:59:34","date_gmt":"2024-10-05T08:59:34","guid":{"rendered":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/?p=522"},"modified":"2024-12-23T10:03:20","modified_gmt":"2024-12-23T09:03:20","slug":"konvertierung-eines-future-in-ein-completablefuture-in-java","status":"publish","type":"post","link":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/?p=522","title":{"rendered":"Konvertierung eines Future in ein CompletableFuture in Java"},"content":{"rendered":"\n<p>Die Java-Programmierung bietet verschiedene Mechanismen f\u00fcr die Arbeit mit asynchronen Aufgaben. Zwei wichtige Bestandteile in diesem Kontext sind das klassische <code>Future<\/code>-Interface und das moderner gestaltete <code>CompletableFuture<\/code>, das mit Java 8 eingef\u00fchrt wurde. W\u00e4hrend beide Konzepte asynchrone Verarbeitung erm\u00f6glichen, unterscheiden sie sich erheblich in ihren Funktionsweisen und M\u00f6glichkeiten. In diesem Artikel gehen wir darauf ein, wie man ein <code>Future<\/code> in ein <code>CompletableFuture<\/code> konvertieren kann, und beleuchten die Unterschiede zwischen beiden Ans\u00e4tzen.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">Unterschiede zwischen Future und CompletableFuture<\/h4>\n\n\n\n<h5 class=\"wp-block-heading\">Future<\/h5>\n\n\n\n<p>Das <code>Future<\/code>-Interface wurde mit Java 5 eingef\u00fchrt und stellt ein einfaches Mittel bereit, um asynchrone Ergebnisse zu verarbeiten. Es erlaubt es, eine Aufgabe auszuf\u00fchren und das Ergebnis zu einem sp\u00e4teren Zeitpunkt abzurufen. Hier sind einige Kernpunkte:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Blockierende Abfrage<\/strong>: Um das Ergebnis zu erhalten, wird die Methode <code>get()<\/code> aufgerufen. Diese blockiert den aktuellen Thread, bis das Ergebnis verf\u00fcgbar ist. <code>Future&lt;String> future = executorService.submit(() -> \"Hello, World!\"); String result = future.get(); \/\/ Blockiert, bis das Ergebnis verf\u00fcgbar ist<\/code><\/li>\n\n\n\n<li><strong>Keine direkte Abbruchm\u00f6glichkeit<\/strong>: Ein <code>Future<\/code> kann zwar \u00fcber die Methode <code>cancel()<\/code> abgebrochen werden, bietet aber keine Mechanismen zur Abfrage, wann oder warum es abgebrochen wurde.<\/li>\n\n\n\n<li><strong>Eingeschr\u00e4nkte Funktionalit\u00e4t<\/strong>: Es gibt keine eingebaute Unterst\u00fctzung f\u00fcr Callback-Mechanismen oder Verkettung von Aufgaben.<\/li>\n<\/ol>\n\n\n\n<h5 class=\"wp-block-heading\">CompletableFuture<\/h5>\n\n\n\n<p>Das <code>CompletableFuture<\/code> wurde mit Java 8 eingef\u00fchrt, um die Einschr\u00e4nkungen des <code>Future<\/code> zu \u00fcberwinden. Es ist Teil der <code>java.util.concurrent<\/code>-Bibliothek und unterst\u00fctzt eine umfangreiche API f\u00fcr asynchrone Programmierung. Einige Highlights:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Non-Blocking<\/strong>: Statt zu blockieren, k\u00f6nnen Callbacks registriert werden, die automatisch ausgef\u00fchrt werden, sobald das Ergebnis verf\u00fcgbar ist. <code>CompletableFuture.supplyAsync(() -> \"Hello, World!\") .thenAccept(System.out::println);<\/code><\/li>\n\n\n\n<li><strong>Kombination von Aufgaben<\/strong>: <code>CompletableFuture<\/code> erm\u00f6glicht die Verkettung mehrerer Aufgaben (z. B. <code>thenApply<\/code>, <code>thenCombine<\/code>).<\/li>\n\n\n\n<li><strong>Manuelle Kontrolle<\/strong>: Es kann manuell abgeschlossen oder beendet werden, wodurch es flexibler ist als das klassische <code>Future<\/code>.<\/li>\n\n\n\n<li><strong>Unterst\u00fctzung f\u00fcr Exception-Handling<\/strong>: Methoden wie <code>exceptionally<\/code> oder <code>handle<\/code> erlauben eine saubere Behandlung von Fehlern.<\/li>\n<\/ol>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">Konvertierung eines Future in ein CompletableFuture<\/h4>\n\n\n\n<p>In bestehenden Projekten ist es oft notwendig, <code>Future<\/code>-Objekte, die von \u00e4lteren APIs bereitgestellt werden, in ein <code>CompletableFuture<\/code> zu konvertieren, um von dessen erweiterten Funktionen zu profitieren. Dies ist leider nicht direkt in der Standardbibliothek enthalten, aber mithilfe von Hilfsfunktionen leicht realisierbar.<\/p>\n\n\n\n<h5 class=\"wp-block-heading\">Implementierung<\/h5>\n\n\n\n<p>Die Grundidee ist, ein neues <code>CompletableFuture<\/code> zu erstellen und den Status eines gegebenen <code>Future<\/code> darauf zu spiegeln. Hier ein m\u00f6gliches Beispiel:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\"><span class=\"hljs-keyword\">import<\/span> java.util.concurrent.*;\n\npublic <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">FutureConverter<\/span> <\/span>{\n\n    public <span class=\"hljs-keyword\">static<\/span> &lt;T&gt; CompletableFuture&lt;T&gt; convertToCompletableFuture(Future&lt;T&gt; future) {\n        CompletableFuture&lt;T&gt; completableFuture = <span class=\"hljs-keyword\">new<\/span> CompletableFuture&lt;&gt;();\n\n        Executors.newSingleThreadExecutor().submit(() -&gt; {\n            <span class=\"hljs-keyword\">try<\/span> {\n                T result = future.get();\n                completableFuture.complete(result);\n            } <span class=\"hljs-keyword\">catch<\/span> (Exception e) {\n                completableFuture.completeExceptionally(e);\n            }\n        });\n\n        <span class=\"hljs-keyword\">return<\/span> completableFuture;\n    }\n\n    public <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">void<\/span> main(<span class=\"hljs-built_in\">String<\/span>&#91;] args) throws ExecutionException, InterruptedException {\n        ExecutorService executorService = Executors.newFixedThreadPool(<span class=\"hljs-number\">1<\/span>);\n        Future&lt;<span class=\"hljs-built_in\">String<\/span>&gt; future = executorService.submit(() -&gt; <span class=\"hljs-string\">\"Hello, CompletableFuture!\"<\/span>);\n\n        CompletableFuture&lt;<span class=\"hljs-built_in\">String<\/span>&gt; completableFuture = convertToCompletableFuture(future);\n\n        completableFuture.thenAccept(System.out::println)\n                         .exceptionally(throwable -&gt; {\n                             System.err.println(<span class=\"hljs-string\">\"Fehler: \"<\/span> + throwable);\n                             <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-literal\">null<\/span>;\n                         });\n\n        executorService.shutdown();\n    }\n}\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h5 class=\"wp-block-heading\">Erkl\u00e4rung<\/h5>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Neues CompletableFuture erstellen<\/strong>: Ein leeres <code>CompletableFuture<\/code> wird erzeugt, das sp\u00e4ter mit dem Ergebnis des <code>Future<\/code> vervollst\u00e4ndigt wird.<\/li>\n\n\n\n<li><strong>Thread-Executor verwenden<\/strong>: Da <code>Future.get()<\/code> blockierend ist, muss es in einem separaten Thread ausgef\u00fchrt werden.<\/li>\n\n\n\n<li><strong>Ergebnis spiegeln<\/strong>: Sobald das <code>Future<\/code> abgeschlossen ist, wird entweder das Ergebnis oder eine Ausnahme an das <code>CompletableFuture<\/code> weitergegeben.<\/li>\n<\/ol>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">Vorteile der Konvertierung<\/h4>\n\n\n\n<p>Die Konvertierung eines <code>Future<\/code> in ein <code>CompletableFuture<\/code> bietet folgende Vorteile:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Erweiterte API<\/strong>: Es kann von Methoden wie <code>thenApply<\/code>, <code>thenCombine<\/code> und <code>handle<\/code> Gebrauch gemacht werden.<\/li>\n\n\n\n<li><strong>Non-Blocking Mechanismen<\/strong>: Statt <code>get()<\/code> zu blockieren, k\u00f6nnen asynchrone Callbacks registriert werden.<\/li>\n\n\n\n<li><strong>Einfache Fehlerbehandlung<\/strong>: Mit Funktionen wie <code>exceptionally<\/code> l\u00e4sst sich eine robuste Fehlerverarbeitung implementieren.<\/li>\n\n\n\n<li><strong>Flexibilit\u00e4t<\/strong>: Aufgaben k\u00f6nnen leicht kombiniert oder Ergebnisse verarbeitet werden, ohne komplexen Boilerplate-Code zu schreiben.<\/li>\n<\/ol>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">Einschr\u00e4nkungen<\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Performance-Overhead<\/strong>: Die Verwendung eines separaten Threads zur Verarbeitung des blockierenden <code>Future.get()<\/code> kann ineffizient sein, insbesondere bei vielen Konvertierungen.<\/li>\n\n\n\n<li><strong>Komplexit\u00e4t der Fehlerbehandlung<\/strong>: Wenn das Original-<code>Future<\/code> unvollst\u00e4ndig bleibt, kann dies unerwartetes Verhalten hervorrufen.<\/li>\n\n\n\n<li><strong>Zus\u00e4tzliche Ressourcen<\/strong>: Der Einsatz eines Executors zur Umwandlung erh\u00f6ht den Ressourcenbedarf.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">Fazit<\/h4>\n\n\n\n<p>Die Konvertierung eines <code>Future<\/code> in ein <code>CompletableFuture<\/code> ist ein n\u00fctzliches Werkzeug, um \u00e4lteren Code mit modernen, nicht-blockierenden APIs zu kombinieren. W\u00e4hrend <code>Future<\/code> einfache, blockierende Abfragen bietet, erm\u00f6glicht <code>CompletableFuture<\/code> eine umfassende und flexible Handhabung von asynchronen Aufgaben. Mit einer durchdachten Konvertierungsstrategie k\u00f6nnen Entwickler die Vorteile der modernen API nutzen, ohne auf bew\u00e4hrte, \u00e4ltere Implementierungen verzichten zu m\u00fcssen. Dennoch sollte man sich der m\u00f6glichen Performance- und Ressourcenkosten bewusst sein und diese bei der Implementierung ber\u00fccksichtigen.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Die Java-Programmierung bietet verschiedene Mechanismen f\u00fcr die Arbeit mit asynchronen Aufgaben. Zwei wichtige Bestandteile in diesem Kontext sind das klassische Future-Interface und das moderner gestaltete CompletableFuture, das mit Java 8 eingef\u00fchrt wurde. W\u00e4hrend beide Konzepte asynchrone Verarbeitung erm\u00f6glichen, unterscheiden sie sich erheblich in ihren Funktionsweisen und M\u00f6glichkeiten. In diesem Artikel gehen wir darauf ein, wie [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4],"tags":[],"class_list":["post-522","post","type-post","status-publish","format-standard","hentry","category-plain_java"],"_links":{"self":[{"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=\/wp\/v2\/posts\/522","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=522"}],"version-history":[{"count":1,"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=\/wp\/v2\/posts\/522\/revisions"}],"predecessor-version":[{"id":523,"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=\/wp\/v2\/posts\/522\/revisions\/523"}],"wp:attachment":[{"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=522"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=522"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=522"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}