{"id":658,"date":"2026-04-09T22:38:00","date_gmt":"2026-04-09T21:38:00","guid":{"rendered":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/?p=658"},"modified":"2026-06-16T22:42:23","modified_gmt":"2026-06-16T21:42:23","slug":"scoped-values-in-java-der-moderne-ersatz-fuer-threadlocal","status":"publish","type":"post","link":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/?p=658","title":{"rendered":"Scoped Values in Java \u2013 Der moderne Ersatz f\u00fcr ThreadLocal"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Jeder Java-Entwickler kennt das Problem: Ein Request trifft ein, der HTTP-Controller startet einen Service, der ruft ein Repository auf \u2013 und irgendwo in der Tiefe des Stacks soll auf die Request-ID oder den aktuellen Benutzer zugegriffen werden. Ohne sie als Parameter durch alle Methoden zu schleppen. Die klassische L\u00f6sung hei\u00dft&nbsp;<code>ThreadLocal<\/code>&nbsp;\u2013 doch die hat gravierende Nachteile. Mit Java 21 (JEP 446) wurde&nbsp;<strong>Scoped Value<\/strong>&nbsp;als Preview-Feature eingef\u00fchrt, das&nbsp;<code>ThreadLocal<\/code>&nbsp;in modernen Codebasen abl\u00f6sen soll. Hinweis: Auch in Java 24 (Stand M\u00e4rz 2025) ist die API noch im Preview-Status (JEP 487) und sollte nicht in Production verwendet werden.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Das Problem mit ThreadLocal<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><code>ThreadLocal<\/code>&nbsp;speichert Daten pro Thread, global erreichbar und implizit vererbt. Das klingt praktisch, f\u00fchrt aber zu diesen Problemen:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Unkontrollierte Mutabilit\u00e4t<\/strong>:\u00a0<code>ThreadLocal.set()<\/code>\u00a0kann von \u00fcberall aufgerufen werden \u2013 eine Einladung f\u00fcr Seiteneffekte<\/li>\n\n\n\n<li><strong>Keine definierte Lebensdauer<\/strong>: Einmal gesetzt bleibt der Wert, bis er aktiv entfernt wird \u2013 Memory Leaks drohen<\/li>\n\n\n\n<li><strong>Probleme mit Virtual Threads<\/strong>: Unter Java 21 k\u00f6nnen Millionen Virtual Threads existieren. Ein\u00a0<code>ThreadLocal<\/code>-wert pro Thread skaliert hier nicht<\/li>\n\n\n\n<li><strong>Kein Scope<\/strong>: Es gibt keine Einschr\u00e4nkung, wo und wie lange ein Wert g\u00fcltig ist<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">ScopedValue \u2013 immutable und scoped<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><code>ScopedValue<\/code>&nbsp;verfolgt einen fundamental anderen Ansatz: Der Wert ist&nbsp;<strong>immutable<\/strong>&nbsp;und nur innerhalb eines definierten&nbsp;<strong>Scopes<\/strong>&nbsp;verf\u00fcgbar.<\/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\">private <span class=\"hljs-keyword\">static<\/span> final ScopedValue&lt;<span class=\"hljs-built_in\">String<\/span>&gt; REQUEST_ID = ScopedValue.newInstance();\n\nScopedValue.where(REQUEST_ID, <span class=\"hljs-string\">\"req-abc-123\"<\/span>)\n    .run(() -&gt; {\n        &lt;em&gt;<span class=\"hljs-comment\">\/\/ In diesem Scope ist der Wert verf\u00fcgbar&lt;\/em&gt;<\/span>\n        System.out.println(REQUEST_ID.get()); <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">em<\/span>&gt;<\/span>\/\/ \"req-abc-123\"<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">em<\/span>&gt;<\/span><\/span>\n    });\n\n<span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">em<\/span>&gt;<\/span>\/\/ Au\u00dferhalb: kein Zugriff \u2013 REQUEST_ID.get() wirft NoSuchElementException<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">em<\/span>&gt;<\/span><\/span>\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<p class=\"wp-block-paragraph\">Der entscheidende Unterschied zu&nbsp;<code>ThreadLocal<\/code>: Der Scope wird explizit ge\u00f6ffnet (<code>where<\/code>) und mit einer Aktion (<code>run<\/code>) verbunden. Beim Verlassen des Scopes ist der Wert automatisch ung\u00fcltig. Kein&nbsp;<code>remove()<\/code>, keine Leaks.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Vererbung an Kind-Threads<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Scoped Values vererben sich automatisch an Kind-Threads \u2013 allerdings nur bei Verwendung von&nbsp;<code>StructuredTaskScope<\/code>&nbsp;(ebenfalls Preview-Feature). Bei manuell erstellten Virtual Threads via&nbsp;<code>Thread.ofVirtual()<\/code>&nbsp;oder&nbsp;<code>Executors.newVirtualThreadPerTaskExecutor()<\/code>&nbsp;findet keine automatische Vererbung statt:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">ScopedValue.where(REQUEST_ID, <span class=\"hljs-string\">\"req-abc-123\"<\/span>)\n    .run(() -&gt; {\n        <span class=\"hljs-keyword\">try<\/span> (<span class=\"hljs-keyword\">var<\/span> scope = <span class=\"hljs-keyword\">new<\/span> StructuredTaskScope&lt;Void&gt;()) {\n            scope.fork(() -&gt; {\n                System.out.println(REQUEST_ID.get()); <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">em<\/span>&gt;<\/span>\/\/ \"req-abc-123\" wird vererbt<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">em<\/span>&gt;<\/span><\/span>\n                <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-literal\">null<\/span>;\n            });\n            scope.join();\n        }\n    });\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><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<p class=\"wp-block-paragraph\">In Kombination mit&nbsp;<strong>Structured Concurrency<\/strong>&nbsp;und&nbsp;<strong>Virtual Threads<\/strong>&nbsp;entsteht ein nahtloses Kontext-Propagation-Modell:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\"><span class=\"hljs-keyword\">try<\/span> (<span class=\"hljs-keyword\">var<\/span> scope = <span class=\"hljs-keyword\">new<\/span> StructuredTaskScope.ShutdownOnFailure()) {\n    scope.fork(() -&gt; apiService.rufeMitKontext());\n    scope.fork(() -&gt; datenbankService.ladeMitKontext());\n    scope.join();\n}\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><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<p class=\"wp-block-paragraph\">Beide Tasks sehen denselben&nbsp;<code>REQUEST_ID<\/code>-Wert, ohne dass er als Parameter \u00fcbergeben oder manuell kopiert wurde.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Vergleich: ThreadLocal vs. ScopedValue<\/h2>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">&lt;em&gt;<span class=\"hljs-comment\">\/\/ ThreadLocal-Ansatz (legacy)&lt;\/em&gt;<\/span>\nThreadLocal&lt;<span class=\"hljs-built_in\">String<\/span>&gt; requestId = <span class=\"hljs-keyword\">new<\/span> ThreadLocal&lt;&gt;();\nrequestId.set(<span class=\"hljs-string\">\"abc\"<\/span>);\n<span class=\"hljs-keyword\">try<\/span> {\n    meinService.verarbeite();\n} <span class=\"hljs-keyword\">finally<\/span> {\n    requestId.remove(); <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">em<\/span>&gt;<\/span>\/\/ Sonst Memory Leak!<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">em<\/span>&gt;<\/span><\/span>\n}\n\n&lt;em&gt;<span class=\"hljs-comment\">\/\/ ScopedValue-Ansatz (modern)&lt;\/em&gt;<\/span>\nprivate <span class=\"hljs-keyword\">static<\/span> final ScopedValue&lt;<span class=\"hljs-built_in\">String<\/span>&gt; REQUEST_ID = ScopedValue.newInstance();\nScopedValue.where(REQUEST_ID, <span class=\"hljs-string\">\"abc\"<\/span>)\n    .run(() -&gt; meinService.verarbeite());\n<span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">em<\/span>&gt;<\/span>\/\/ Kein finally, kein remove \u2013 Scope ist automatisch begrenzt<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">em<\/span>&gt;<\/span><\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><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<h2 class=\"wp-block-heading\">Mehrere Werte kombinieren<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Scoped Values lassen sich mit&nbsp;<code>where(...).where(...)<\/code>&nbsp;ketten:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">final<\/span> ScopedValue&lt;String&gt; REQUEST_ID = ScopedValue.newInstance();\n<span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">final<\/span> ScopedValue&lt;User&gt;   CURRENT_USER = ScopedValue.newInstance();\n\nScopedValue.where(REQUEST_ID, <span class=\"hljs-string\">\"abc\"<\/span>)\n    .where(CURRENT_USER, user)\n    .run(() -&gt; {\n        log.info(<span class=\"hljs-string\">\"User {} in Request {}\"<\/span>, CURRENT_USER.get(), REQUEST_ID.get());\n    });\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\">Rebind \u2013 Wert \u00fcberschreiben innerhalb eines Scopes<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Mit&nbsp;<code>callWhere<\/code>&nbsp;l\u00e4sst sich ein Wert innerhalb eines bestehenden Scopes tempor\u00e4r \u00fcberschreiben:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">ScopedValue.where(REQUEST_ID, <span class=\"hljs-string\">\"outer\"<\/span>)\n    .run(() -&gt; {\n        System.out.println(REQUEST_ID.get()); <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">em<\/span>&gt;<\/span>\/\/ \"outer\"<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">em<\/span>&gt;<\/span><\/span>\n        ScopedValue.where(REQUEST_ID, <span class=\"hljs-string\">\"inner\"<\/span>)\n            .run(() -&gt; {\n                System.out.println(REQUEST_ID.get()); <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">em<\/span>&gt;<\/span>\/\/ \"inner\"<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">em<\/span>&gt;<\/span><\/span>\n            });\n        System.out.println(REQUEST_ID.get()); <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">em<\/span>&gt;<\/span>\/\/ \"outer\" wiederhergestellt<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">em<\/span>&gt;<\/span><\/span>\n    });\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><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<p class=\"wp-block-paragraph\">Dieses Rebind ist ein wichtiger Unterschied zu&nbsp;<code>ThreadLocal<\/code>, wo&nbsp;<code>set()<\/code>&nbsp;den Wert global-mutabel \u00fcberschreibt.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Virtual Threads und Speicher<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Ein zentrales Problem von&nbsp;<code>ThreadLocal<\/code>&nbsp;unter Virtual Threads ist der Speicher. Platform Threads (einige Hundert) mit einem&nbsp;<code>ThreadLocal&lt;String&gt;<\/code>&nbsp;machen kaum etwas aus. Aber eine Million Virtual Threads, jeder mit seinem eigenen&nbsp;<code>ThreadLocal<\/code>-Wert, summieren sich massiv.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>ScopedValue<\/code>&nbsp;l\u00f6st das \u00fcber strukturelles Teilen: Da der Wert immutable ist und vom Eltern-Thread vererbt wird, teilen sich Kind-Threads dieselbe Referenz \u2013 kein Kopieren, keine Duplizierung:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">ScopedValue.where(REQUEST_ID, <span class=\"hljs-string\">\"abc\"<\/span>)\n    .run(() -&gt; {\n        <span class=\"hljs-keyword\">try<\/span> (<span class=\"hljs-keyword\">var<\/span> scope = <span class=\"hljs-keyword\">new<\/span> StructuredTaskScope&lt;Void&gt;()) {\n            <span class=\"hljs-keyword\">for<\/span> (int i = <span class=\"hljs-number\">0<\/span>; i &lt; <span class=\"hljs-number\">100000<\/span>; i++) {\n                scope.fork(() -&gt; {\n                    assert REQUEST_ID.get().equals(<span class=\"hljs-string\">\"abc\"<\/span>);\n                    <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-literal\">null<\/span>;\n                });\n            }\n            scope.join();\n        }\n    });\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><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<p class=\"wp-block-paragraph\">100.000 Virtual Threads greifen hier auf denselben&nbsp;<code>ScopedValue<\/code>&nbsp;zu \u2013 mit&nbsp;<code>ThreadLocal<\/code>&nbsp;m\u00fcsste der Wert 100.000-mal kopiert werden.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Migration von ThreadLocal<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Wer eine bestehende&nbsp;<code>ThreadLocal<\/code>-Basis migrieren will, kann schrittweise vorgehen:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-8\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">&lt;em&gt;<span class=\"hljs-comment\">\/\/ Vorher: ThreadLocal&lt;\/em&gt;<\/span>\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">RequestContext<\/span> <\/span>{\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">final<\/span> ThreadLocal&lt;String&gt; requestId = <span class=\"hljs-keyword\">new<\/span> ThreadLocal&lt;&gt;();\n\n    <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">static<\/span> void setRequestId(String id) {\n        requestId.set(id);\n    }\n\n    <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">static<\/span> String getRequestId() {\n        <span class=\"hljs-keyword\">return<\/span> requestId.get();\n    }\n}\n\n&lt;em&gt;<span class=\"hljs-comment\">\/\/ Nachher: ScopedValue&lt;\/em&gt;<\/span>\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">RequestContext<\/span> <\/span>{\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">final<\/span> ScopedValue&lt;String&gt; REQUEST_ID =\n        ScopedValue.newInstance();\n\n    <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">static<\/span> void withRequestId(String id, Runnable action) {\n        ScopedValue.where(REQUEST_ID, id).run(action);\n    }\n\n    <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">static<\/span> String getRequestId() {\n        <span class=\"hljs-keyword\">return<\/span> REQUEST_ID.get();\n    }\n}\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-8\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Der Unterschied: Statt eines flachen&nbsp;<code>set()<\/code>&nbsp;wird jetzt ein Scope ben\u00f6tigt. Das&nbsp;<code>Runnable<\/code>&nbsp;zwingt den Aufrufer, den G\u00fcltigkeitsbereich explizit zu machen \u2013 ein struktureller Vorteil, der Debugging und Wartung vereinfacht.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Fazit<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Scoped Values sind mehr als ein&nbsp;<code>ThreadLocal<\/code>-Ersatz \u2013 sie sind ein Paradigmenwechsel im Umgang mit Thread-lokalen Daten. Die Immutability, der definierte Lebenszyklus und die automatische Vererbung an Virtual Threads machen sie zur nat\u00fcrlichen Wahl f\u00fcr Java 21+ Projekte. Besonders unter Virtual Threads, wo tausende Threads gleichzeitig laufen k\u00f6nnen, sind Scoped Values durch ihre Referenz-Teilung dem kopierenden&nbsp;<code>ThreadLocal<\/code>&nbsp;\u00fcberlegen. In Verbindung mit Structured Concurrency entsteht ein Programmiermodell, das funktionale Reinheit mit nebenl\u00e4ufiger Leistungsf\u00e4higkeit verbindet.&nbsp;<code>ThreadLocal<\/code>&nbsp;sollte nur noch f\u00fcr Legacy-Code oder spezielle Low-Level-Anwendungen genutzt werden.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Wichtig<\/strong>: Sowohl Scoped Values als auch Structured Concurrency sind in Java 24 (Stand M\u00e4rz 2025) noch Preview-Features und nicht f\u00fcr den produktiven Einsatz empfohlen. Die APIs sind stabil, k\u00f6nnen sich aber noch \u00e4ndern. F\u00fcr Production-Code sollte weiterhin&nbsp;<code>ThreadLocal<\/code>&nbsp;verwendet werden, bis diese Features final sind.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Jeder Java-Entwickler kennt das Problem: Ein Request trifft ein, der HTTP-Controller startet einen Service, der ruft ein Repository auf \u2013 und irgendwo in der Tiefe des Stacks soll auf die Request-ID oder den aktuellen Benutzer zugegriffen werden. Ohne sie als Parameter durch alle Methoden zu schleppen. Die klassische L\u00f6sung hei\u00dft&nbsp;ThreadLocal&nbsp;\u2013 doch die hat gravierende Nachteile. [&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-658","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\/658","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=658"}],"version-history":[{"count":1,"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=\/wp\/v2\/posts\/658\/revisions"}],"predecessor-version":[{"id":659,"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=\/wp\/v2\/posts\/658\/revisions\/659"}],"wp:attachment":[{"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=658"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=658"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=658"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}