<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Machine coding Master</title>
    <description>The latest articles on DEV Community by Machine coding Master (@machinecodingmaster).</description>
    <link>https://dev.to/machinecodingmaster</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3894844%2F09f3cafa-c542-4beb-8efa-72045647d766.png</url>
      <title>DEV Community: Machine coding Master</title>
      <link>https://dev.to/machinecodingmaster</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/machinecodingmaster"/>
    <language>en</language>
    <item>
      <title>Java &amp; AI: What Developers Need to Know</title>
      <dc:creator>Machine coding Master</dc:creator>
      <pubDate>Sat, 06 Jun 2026 06:08:21 +0000</pubDate>
      <link>https://dev.to/machinecodingmaster/java-ai-what-developers-need-to-know-5555</link>
      <guid>https://dev.to/machinecodingmaster/java-ai-what-developers-need-to-know-5555</guid>
      <description>&lt;h2&gt;
  
  
  Stop Letting Claude Write Java 8: How to Force JDK 26 Idioms in Your .cursorrules
&lt;/h2&gt;

&lt;p&gt;If you are still letting Claude or GPT-4o spit out legacy Java 8/11 boilerplate in 2026, you are wasting your subscription. Your AI assistant doesn't know you've upgraded to JDK 26 unless you force its hand with strict, opinionated workspace rules.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Most Developers Get This Wrong
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Relying on default LLM system prompts:&lt;/strong&gt; Out-of-the-box models default to the most common internet data, meaning you get deprecated &lt;code&gt;ThreadLocal&lt;/code&gt; patterns and bloated &lt;code&gt;CompletableFuture&lt;/code&gt; chains.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Ignoring Virtual Thread safety:&lt;/strong&gt; AI tools love generating heavy &lt;code&gt;synchronized&lt;/code&gt; blocks and thread-local caches, which pin carrier threads and destroy virtual thread throughput.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Assuming the AI knows your stack:&lt;/strong&gt; Without explicit workspace boundaries, the model will continuously hallucinate mixed-version code, combining JDK 21 record patterns with ancient Apache Commons utilities.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Right Way
&lt;/h2&gt;

&lt;p&gt;To get clean, performant, and modern Java code, you must hardcode JDK 26 idioms directly into your workspace &lt;code&gt;.cursorrules&lt;/code&gt; or &lt;code&gt;.claudecode&lt;/code&gt; configurations.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Ban Legacy Concurrency:&lt;/strong&gt; Explicitly forbid &lt;code&gt;ThreadLocal&lt;/code&gt; and &lt;code&gt;ExecutorService&lt;/code&gt; in favor of JEP 480 Structured Concurrency and Scoped Values.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Mandate Virtual Thread Safety:&lt;/strong&gt; Rule-bind the AI to avoid locking carrier threads by replacing &lt;code&gt;synchronized&lt;/code&gt; with &lt;code&gt;ReentrantLock&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Enforce Pattern Matching &amp;amp; Records:&lt;/strong&gt; Demand the use of record patterns, sealed interfaces, and modern switch expressions for all data modeling.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Show Me The Code (or Example)
&lt;/h2&gt;

&lt;p&gt;Add this snippet to your &lt;code&gt;.cursorrules&lt;/code&gt; or &lt;code&gt;.claudecode&lt;/code&gt; file in your repository root:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# JDK 26 Concurrency Rules&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; NEVER use ThreadLocal. ALWAYS use ScopedValue.
&lt;span class="p"&gt;-&lt;/span&gt; NEVER use CompletableFuture for task orchestration. Use JEP 480 StructuredTaskScope.
&lt;span class="p"&gt;-&lt;/span&gt; Avoid 'synchronized' blocks to prevent carrier thread pinning; use ReentrantLock.

&lt;span class="gh"&gt;# Example of Expected Concurrency Pattern:&lt;/span&gt;
try (var scope = new StructuredTaskScope.ShutdownOnFailure()) {
    Subtask&lt;span class="nt"&gt;&amp;lt;String&amp;gt;&lt;/span&gt; task = scope.fork(() -&amp;gt; fetchUserData());
    scope.join().throwIfFailed();
    return task.get();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;LLMs are historically biased:&lt;/strong&gt; Without a &lt;code&gt;.cursorrules&lt;/code&gt; file, your AI assistant will default to 2014-era Java boilerplate.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Virtual threads demand new patterns:&lt;/strong&gt; Legacy thread-safety patterns kill virtual thread performance—your prompt configuration is your first line of defense.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Automate your standards:&lt;/strong&gt; Commit your AI configuration files to git so your entire team instantly generates optimized, modern JDK 26 code.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;If you're prepping for interviews, I've been building &lt;a href="https://javalld.com" rel="noopener noreferrer"&gt;javalld.com&lt;/a&gt; — real machine coding problems with full execution traces.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;---JSON&lt;br&gt;
{"title": "Stop Letting Claude Write Java 8: How to Force JDK 26 Idioms in Your .cursorrules", "tags": ["java", "productivity", "concurrency", "ai"]}&lt;br&gt;
---END---&lt;/p&gt;

</description>
      <category>java</category>
      <category>programming</category>
      <category>ai</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Stop Leaking Trace Context: How to Migrate OpenTelemetry to JDK 26 Scoped Values</title>
      <dc:creator>Machine coding Master</dc:creator>
      <pubDate>Fri, 05 Jun 2026 06:50:19 +0000</pubDate>
      <link>https://dev.to/machinecodingmaster/stop-leaking-trace-context-how-to-migrate-opentelemetry-to-jdk-26-scoped-values-5401</link>
      <guid>https://dev.to/machinecodingmaster/stop-leaking-trace-context-how-to-migrate-opentelemetry-to-jdk-26-scoped-values-5401</guid>
      <description>&lt;h2&gt;
  
  
  Stop Leaking Trace Context: How to Migrate OpenTelemetry to JDK 26 Scoped Values
&lt;/h2&gt;

&lt;p&gt;If you are still relying on traditional &lt;code&gt;ThreadLocal&lt;/code&gt; storage for OpenTelemetry context propagation under JDK 26's virtual threads, you are sitting on a production time bomb. Millions of concurrent virtual threads will quickly turn your heap into a graveyard of leaked trace contexts and bloated memory overhead.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you're prepping for interviews, I've been building &lt;a href="https://javalld.com" rel="noopener noreferrer"&gt;javalld.com&lt;/a&gt; — real machine coding problems with full execution traces.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Why Most Developers Get This Wrong
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Defaulting to ThreadLocal:&lt;/strong&gt; Assuming the default OpenTelemetry &lt;code&gt;ThreadLocal&lt;/code&gt; storage works fine with virtual threads, ignoring the heavy heap footprint and context drift when threads are unmounted and rescheduled.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ignoring Context Leakage:&lt;/strong&gt; Forgetting that &lt;code&gt;ThreadLocal&lt;/code&gt; values persist unless explicitly removed, causing trace data to bleed into unrelated tasks on shared carrier threads.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Manual Propagation Mess:&lt;/strong&gt; Manually passing &lt;code&gt;Span&lt;/code&gt; objects down the call stack instead of leveraging JDK 26's native scoped value propagation.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Right Way
&lt;/h2&gt;

&lt;p&gt;The clean solution is to bind OpenTelemetry's &lt;code&gt;ContextStorage&lt;/code&gt; directly to JEP 487 Scoped Values to enforce immutable, automatic, and thread-safe context propagation across virtual threads and structured concurrency boundaries.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Implement Custom ContextStorage:&lt;/strong&gt; Create an OTel &lt;code&gt;ContextStorage&lt;/code&gt; implementation backed by a static &lt;code&gt;ScopedValue&amp;lt;Context&amp;gt;&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enforce Immutability:&lt;/strong&gt; Leverage the immutable nature of &lt;code&gt;ScopedValue&lt;/code&gt; to prevent downstream child threads from accidentally mutating the parent's tracing context.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Leverage Structured Concurrency:&lt;/strong&gt; Use &lt;code&gt;StructuredTaskScope&lt;/code&gt; which automatically inherits the scoped trace context without manual boilerplate.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Show Me The Code
&lt;/h2&gt;

&lt;p&gt;Here is how to run a span using JDK 26 &lt;code&gt;ScopedValue&lt;/code&gt; for zero-leak, zero-overhead propagation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ScopedTraceRunner&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;ScopedValue&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Span&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;ACTIVE_SPAN&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ScopedValue&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;newInstance&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Span&lt;/span&gt; &lt;span class="n"&gt;span&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Runnable&lt;/span&gt; &lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Bind span immutably to the current scope&lt;/span&gt;
        &lt;span class="nc"&gt;ScopedValue&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;where&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;ACTIVE_SPAN&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;span&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="o"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;scope&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;span&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;makeCurrent&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt; 
            &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;// Span scope closes cleanly here&lt;/span&gt;
        &lt;span class="o"&gt;});&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Zero Memory Overhead:&lt;/strong&gt; &lt;code&gt;ScopedValue&lt;/code&gt; is optimized for millions of virtual threads, avoiding the heavy thread-local map overhead.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Strict Scope Lifecycle:&lt;/strong&gt; Contexts are automatically unbound when the execution block exits, completely eliminating trace leakage.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Native Structured Concurrency:&lt;/strong&gt; Child threads spawned inside a &lt;code&gt;StructuredTaskScope&lt;/code&gt; automatically inherit scoped trace contexts without manual configuration.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>java</category>
      <category>concurrency</category>
      <category>systemdesign</category>
      <category>programming</category>
    </item>
    <item>
      <title>Stop Blocking Virtual Threads: Building Asynchronous Human-in-the-Loop AI Agents with Spring AI</title>
      <dc:creator>Machine coding Master</dc:creator>
      <pubDate>Thu, 04 Jun 2026 07:08:47 +0000</pubDate>
      <link>https://dev.to/machinecodingmaster/stop-blocking-virtual-threads-building-asynchronous-human-in-the-loop-ai-agents-with-spring-ai-49pp</link>
      <guid>https://dev.to/machinecodingmaster/stop-blocking-virtual-threads-building-asynchronous-human-in-the-loop-ai-agents-with-spring-ai-49pp</guid>
      <description>&lt;h2&gt;
  
  
  Stop Blocking Virtual Threads: Building Asynchronous Human-in-the-Loop AI Agents with Spring AI
&lt;/h2&gt;

&lt;p&gt;In 2026, letting autonomous AI agents execute high-risk enterprise tools without human oversight is a production liability, but blocking platform threads—or even Project Loom’s virtual threads—for hours waiting for a manager's Slack approval is absolute architectural malpractice. We must transition from synchronous execution loops to stateless, event-driven agent hydration where the LLM's reasoning state is serialized and persisted during human-in-the-loop (HITL) interrupts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Most Developers Get This Wrong
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Virtual Thread Abuse:&lt;/strong&gt; Thinking Virtual Threads (&lt;code&gt;VirtualThreadExecutor&lt;/code&gt;) solve the wait problem—they do not; holding resources open for a 4-hour human coffee break destroys system scalability and ruins connection pools.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;State-in-Memory Antipattern:&lt;/strong&gt; Storing the active ReAct loop state (like active &lt;code&gt;ChatMemory&lt;/code&gt; or agent context) in local heap memory, making your system highly vulnerable to redeployments and node failures.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Polled-Waiting Loops:&lt;/strong&gt; Using &lt;code&gt;CompletableFuture&lt;/code&gt; or busy-waiting database polling loops to check if a human has clicked "Approve" on an external UI.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Right Way
&lt;/h2&gt;

&lt;p&gt;The clean solution is to serialize the agent's execution state—the ReAct loop token history, tool call IDs, and pending variables—to a persistent store, terminate the active thread immediately, and hydrate a brand-new agent instance when the approval webhook fires.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Explicit Interrupt Exceptions:&lt;/strong&gt; Throw a specialized &lt;code&gt;AgentSuspensionException&lt;/code&gt; containing the serialized &lt;code&gt;stateId&lt;/code&gt; and tool execution metadata when a high-risk tool is triggered.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;State Hydration:&lt;/strong&gt; Use Spring AI's &lt;code&gt;ChatClient&lt;/code&gt; with a custom Redis-backed &lt;code&gt;ChatMemory&lt;/code&gt; implementation that supports snapshotting at specific message indices.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Asynchronous Resumption:&lt;/strong&gt; Expose a stateless REST endpoint &lt;code&gt;/api/v1/agent/resume&lt;/code&gt; that accepts the human decision, merges it into the serialized history as a &lt;code&gt;ToolResponseMessage&lt;/code&gt;, and triggers the next step of the ReAct loop.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Show Me The Code
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@PostMapping&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/agent/resume"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;resumeAgent&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@RequestBody&lt;/span&gt; &lt;span class="nc"&gt;ApprovalResponse&lt;/span&gt; &lt;span class="n"&gt;approval&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// 1. Retrieve serialized chat history (ReAct state) from Redis&lt;/span&gt;
    &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Message&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;history&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;stateRepository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;findById&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;approval&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;stateId&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;

    &lt;span class="c1"&gt;// 2. Inject the human's decision as if it were the tool's output&lt;/span&gt;
    &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;toolOutput&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;approval&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;approved&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="s"&gt;"Approved: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;approval&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;notes&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Rejected by human"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;history&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ToolResponseMessage&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;approval&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toolCallId&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;toolOutput&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;

    &lt;span class="c1"&gt;// 3. Hydrate the agent and resume execution without blocking threads&lt;/span&gt;
    &lt;span class="nc"&gt;ChatResponse&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;chatClient&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;prompt&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;messages&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;history&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;call&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;chatResponse&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ok&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getResult&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;getOutput&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;getContent&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Never block on humans:&lt;/strong&gt; Treat human approvals as asynchronous, event-driven inputs, not long-lived synchronous I/O operations.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Serialize the prompt history:&lt;/strong&gt; Store the exact LLM prompt/response state to Redis or Postgres to ensure your agents are completely stateless between tool calls.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Leverage Spring AI's modularity:&lt;/strong&gt; Use custom &lt;code&gt;ChatMemory&lt;/code&gt; adapters to dynamically hydrate and dehydrate context windows on demand.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Heads up:&lt;/strong&gt; if you want to see these patterns applied to real interview problems, &lt;a href="https://javalld.com" rel="noopener noreferrer"&gt;javalld.com&lt;/a&gt; has full machine coding solutions with traces.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>java</category>
      <category>ai</category>
      <category>llm</category>
      <category>concurrency</category>
    </item>
    <item>
      <title>Java LLD: Designing a Robust Vehicle Rental System</title>
      <dc:creator>Machine coding Master</dc:creator>
      <pubDate>Wed, 03 Jun 2026 07:24:21 +0000</pubDate>
      <link>https://dev.to/machinecodingmaster/java-lld-designing-a-robust-vehicle-rental-system-8kb</link>
      <guid>https://dev.to/machinecodingmaster/java-lld-designing-a-robust-vehicle-rental-system-8kb</guid>
      <description>&lt;h2&gt;
  
  
  Java LLD: Designing a Robust Vehicle Rental System
&lt;/h2&gt;

&lt;p&gt;Designing a Vehicle Rental System is a classic Low-Level Design (LLD) question frequently asked at companies like Uber, Grab, and Amazon. While the requirements seem simple on the surface, candidates often struggle to handle complex state transitions and dynamic pricing models cleanly under pressure.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Mistake Most Candidates Make
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Monolithic State Management:&lt;/strong&gt; Using massive, nested &lt;code&gt;if-else&lt;/code&gt; or &lt;code&gt;switch-case&lt;/code&gt; blocks inside the &lt;code&gt;Vehicle&lt;/code&gt; class to handle state transitions, leading to spaghetti code.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Hardcoded Pricing Logic:&lt;/strong&gt; Embedding billing and pricing calculations directly inside the reservation flow, making it incredibly difficult to support dynamic or holiday rates.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Weak State Encapsulation:&lt;/strong&gt; Allowing illegal state transitions (such as moving a vehicle directly from &lt;code&gt;Reserved&lt;/code&gt; to &lt;code&gt;UnderMaintenance&lt;/code&gt;) due to scattered validation logic.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Right Approach
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Core mental model:&lt;/strong&gt; Model the vehicle's lifecycle as a self-contained state machine using the State Pattern, delegating transition rules directly to individual state objects.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Key entities/classes:&lt;/strong&gt; &lt;code&gt;Vehicle&lt;/code&gt;, &lt;code&gt;VehicleState&lt;/code&gt; (interface), &lt;code&gt;AvailableState&lt;/code&gt;, &lt;code&gt;ReservedState&lt;/code&gt;, &lt;code&gt;RentedState&lt;/code&gt;, &lt;code&gt;UnderMaintenanceState&lt;/code&gt;, &lt;code&gt;PricingStrategy&lt;/code&gt;, &lt;code&gt;VehicleFactory&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Why it beats the naive approach:&lt;/strong&gt; It strictly enforces the Open-Closed Principle, allowing you to add new states (like &lt;code&gt;Damaged&lt;/code&gt; or &lt;code&gt;InTransit&lt;/code&gt;) or billing rules without modifying existing classes.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;I built &lt;a href="https://javalld.com" rel="noopener noreferrer"&gt;javalld.com&lt;/a&gt; while prepping for senior roles — complete LLD problems with execution traces, not just theory.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  The Key Insight (Code)
&lt;/h2&gt;

&lt;p&gt;Here is how you cleanly reject illegal transitions at the state level using the State Pattern:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;VehicleState&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;reserve&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Vehicle&lt;/span&gt; &lt;span class="n"&gt;vehicle&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;rent&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Vehicle&lt;/span&gt; &lt;span class="n"&gt;vehicle&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;RentedState&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;VehicleState&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;reserve&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Vehicle&lt;/span&gt; &lt;span class="n"&gt;vehicle&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;IllegalStateException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Cannot reserve a rented vehicle!"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;rent&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Vehicle&lt;/span&gt; &lt;span class="n"&gt;vehicle&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;IllegalStateException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Vehicle is already rented!"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;State Pattern Enforces Constraints:&lt;/strong&gt; Moving transition rules into dedicated state classes ensures illegal actions throw exceptions naturally, eliminating conditional clutter.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Strategy Pattern Decouples Billing:&lt;/strong&gt; Separating pricing algorithms from the vehicle entity allows you to dynamically swap rates (e.g., hourly, weekly, or surge pricing).&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Factory Pattern Centralizes Creation:&lt;/strong&gt; Using a factory to instantiate different vehicle types (e.g., Cars, Bikes) keeps your client code decoupled from concrete implementations.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Full working implementation with execution trace available at &lt;a href="https://javalld.com/problems/vehicle-rental" rel="noopener noreferrer"&gt;https://javalld.com/problems/vehicle-rental&lt;/a&gt;&lt;/p&gt;

</description>
      <category>java</category>
      <category>systemdesign</category>
      <category>oop</category>
      <category>interview</category>
    </item>
    <item>
      <title>Java &amp; AI: What Developers Need to Know</title>
      <dc:creator>Machine coding Master</dc:creator>
      <pubDate>Tue, 02 Jun 2026 07:11:09 +0000</pubDate>
      <link>https://dev.to/machinecodingmaster/java-ai-what-developers-need-to-know-4l93</link>
      <guid>https://dev.to/machinecodingmaster/java-ai-what-developers-need-to-know-4l93</guid>
      <description>&lt;h2&gt;
  
  
  Stop Parsing Untrusted LLM JSON: Enforce GPT-5 Strict Schemas with Java 26 Class-File API
&lt;/h2&gt;

&lt;p&gt;In 2026, relying on Jackson to parse loose, non-deterministic JSON from LLMs is architectural malpractice. With GPT-5 offering mathematically guaranteed schema adherence, we can now use the JDK 26 Class-File API (JEP 466) to dynamically extract bytecode schemas at startup, bypassing reflection entirely.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Most Developers Get This Wrong
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Failing gracefully is still failing:&lt;/strong&gt; Developers are still writing defensive try-catch blocks around Jackson &lt;code&gt;ObjectMapper&lt;/code&gt; to handle malformed JSON, instead of forcing the model to adhere to a strict schema at the API boundary.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reflection overhead:&lt;/strong&gt; Using traditional reflection-based JSON schema generators at runtime introduces massive cold-start latency and CPU overhead in high-throughput microservices.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ignoring GPT-5's Strict Mode:&lt;/strong&gt; Passing raw prompt instructions like "return JSON" instead of utilizing the &lt;code&gt;response_format&lt;/code&gt; JSON Schema constraint, which guarantees 100% grammar-based compliance.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Right Way
&lt;/h2&gt;

&lt;p&gt;Compile your target Java Record into a lightweight schema payload using the JDK 26 Class-File API, and feed it directly to GPT-5 to guarantee type-safe responses.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Zero-Reflection Validation:&lt;/strong&gt; Use &lt;code&gt;java.lang.classfile.ClassFile&lt;/code&gt; to parse your compiled Java Records at startup to build your JSON schema.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enforce Strict Mode:&lt;/strong&gt; Always set &lt;code&gt;response_format: { type: "json_schema", json_schema: { strict: true, ... } }&lt;/code&gt; in your GPT-5 API calls.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Type-Safe Mapping:&lt;/strong&gt; Map the mathematically guaranteed LLM response directly to your record components, eliminating runtime parsing errors.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Shameless plug: &lt;a href="https://javalld.com" rel="noopener noreferrer"&gt;javalld.com&lt;/a&gt; has full LLD implementations with step-by-step execution traces — free to use while prepping.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Show Me The Code
&lt;/h2&gt;

&lt;p&gt;Here is how you parse a Java Record using the JDK 26 Class-File API to build a strict GPT-5 schema payload without reflection:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Parse bytecode natively using JDK 26 Class-File API (JEP 466)&lt;/span&gt;
&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;bytes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ClassLoader&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getSystemResourceAsStream&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"com/app/User.class"&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;readAllBytes&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="nc"&gt;ClassModel&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ClassFile&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;parse&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bytes&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;schemaProperties&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;methods&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;filter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;flags&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;has&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;AccessFlag&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;PUBLIC&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;methodName&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;stringValue&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;equals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&amp;lt;init&amp;gt;"&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;collect&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Collectors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toMap&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;methodName&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;stringValue&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt;
        &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"type"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mapDescriptorToType&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;methodType&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;stringValue&lt;/span&gt;&lt;span class="o"&gt;()))&lt;/span&gt;
    &lt;span class="o"&gt;));&lt;/span&gt;

&lt;span class="c1"&gt;// Send strictly structured payload to GPT-5&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;gpt5Request&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"model"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"gpt-5"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"response_format"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
        &lt;span class="s"&gt;"type"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"json_schema"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;"json_schema"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"name"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"user_schema"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"strict"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"schema"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; 
            &lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"type"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"object"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"properties"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;schemaProperties&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"required"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;schemaProperties&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;keySet&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;toList&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt; &lt;span class="s"&gt;"additionalProperties"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
    &lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Stop guessing:&lt;/strong&gt; GPT-5's strict schema enforcement guarantees 100% structural accuracy, making runtime JSON parsing errors a thing of the past.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Embrace JEP 466:&lt;/strong&gt; The JDK 26 Class-File API replaces outdated ASM/ByteBuddy hacks, allowing you to inspect and generate bytecode natively.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Performance is a feature:&lt;/strong&gt; Eliminating reflection in your LLM-to-Java pipeline drops startup and ingestion latency by up to 40% under heavy enterprise loads.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;---JSON&lt;br&gt;
{"title": "Stop Parsing Untrusted LLM JSON: Enforce GPT-5 Strict Schemas with Java 26 Class-File API", "tags": ["java", "ai", "llm", "systemdesign"]}&lt;br&gt;
---END---&lt;/p&gt;

</description>
      <category>java</category>
      <category>programming</category>
      <category>ai</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Stop Burning Cash on Long-Context RAG: Ephemeral Prompt Caching with Spring AI and JTokkit</title>
      <dc:creator>Machine coding Master</dc:creator>
      <pubDate>Sun, 31 May 2026 06:41:33 +0000</pubDate>
      <link>https://dev.to/machinecodingmaster/stop-burning-cash-on-long-context-rag-ephemeral-prompt-caching-with-spring-ai-and-jtokkit-3chc</link>
      <guid>https://dev.to/machinecodingmaster/stop-burning-cash-on-long-context-rag-ephemeral-prompt-caching-with-spring-ai-and-jtokkit-3chc</guid>
      <description>&lt;h2&gt;
  
  
  Stop Burning Cash on Long-Context RAG: Ephemeral Prompt Caching with Spring AI and JTokkit
&lt;/h2&gt;

&lt;p&gt;If your enterprise RAG pipeline is processing megabytes of legal documents or codebase context, you are likely burning thousands of dollars daily on redundant input tokens. Ephemeral prompt caching can slash these LLM costs by up to 90%, but only if you align your token boundaries perfectly inside your Java backend.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Most Developers Get This Wrong
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Blindly trusting Spring AI's defaults:&lt;/strong&gt; Relying on default &lt;code&gt;ChatClient&lt;/code&gt; configurations without verifying token boundaries, causing cache misses on every slight prompt variation.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Ignoring the 1024-token floor:&lt;/strong&gt; Underestimating the strict minimum boundary requirements of providers like Anthropic or OpenAI, leading to zero cache hits for smaller context chunks.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Dynamic pollution:&lt;/strong&gt; Appending dynamic user queries &lt;em&gt;before&lt;/em&gt; the static system context, which instantly invalidates the entire downstream prefix cache.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Right Way
&lt;/h2&gt;

&lt;p&gt;To guarantee a 90% cache hit rate, you must isolate your heavy, immutable context at the front of the prompt and programmatically verify token boundaries using JTokkit before hitting the LLM API.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Strict Prefix Ordering:&lt;/strong&gt; Place your massive PDF knowledge bases or database schemas at the absolute beginning of the prompt sequence.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Programmatic Verification:&lt;/strong&gt; Use JTokkit's &lt;code&gt;EncodingRegistry&lt;/code&gt; to calculate the exact token count, ensuring your cached prefix meets the provider's minimum threshold (e.g., 1024 tokens for Claude 3.5).&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Spring AI Advisor Decoupling:&lt;/strong&gt; Implement a custom &lt;code&gt;AroundAdvisor&lt;/code&gt; to intercept the chat request and inject vendor-specific caching headers dynamically.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Show Me The Code (or Example)
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Verify 1024-token minimum with JTokkit before enabling Ephemeral Caching&lt;/span&gt;
&lt;span class="nc"&gt;Encoding&lt;/span&gt; &lt;span class="n"&gt;enc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;LazyEncodingRegistry&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getRegistry&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;getEncoding&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;EncodingType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;CL100K_BASE&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;enc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;countTokens&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;systemContext&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;chatClient&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;prompt&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;advisors&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;EphemeralCacheAdvisor&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="c1"&gt;// Custom Spring AI Advisor injecting "type": "ephemeral"&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;system&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sp&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;sp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;systemContext&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;userQuery&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;call&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Prefix is King:&lt;/strong&gt; Cacheable content must live strictly at the start of your payload; a single character change before it invalidates the cache.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Assert, Don't Guess:&lt;/strong&gt; Use JTokkit to programmatically assert the 1024-token minimum before committing to cache headers.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Clean Architecture:&lt;/strong&gt; Keep your business logic clean by delegating caching headers to custom Spring AI &lt;code&gt;ChatClient&lt;/code&gt; Advisors.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Heads up:&lt;/strong&gt; if you want to see these patterns applied to real interview problems, &lt;a href="https://javalld.com" rel="noopener noreferrer"&gt;javalld.com&lt;/a&gt; has full machine coding solutions with traces.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>java</category>
      <category>ai</category>
      <category>llm</category>
      <category>systemdesign</category>
    </item>
    <item>
      <title>JDK 26 Pitfalls: Why CPU-Bound Tasks are Killing Your Virtual Threads</title>
      <dc:creator>Machine coding Master</dc:creator>
      <pubDate>Sat, 30 May 2026 06:01:53 +0000</pubDate>
      <link>https://dev.to/machinecodingmaster/jdk-26-pitfalls-why-cpu-bound-tasks-are-killing-your-virtual-threads-5545</link>
      <guid>https://dev.to/machinecodingmaster/jdk-26-pitfalls-why-cpu-bound-tasks-are-killing-your-virtual-threads-5545</guid>
      <description>&lt;h2&gt;
  
  
  JDK 26 Pitfalls: Why CPU-Bound Tasks are Killing Your Virtual Threads
&lt;/h2&gt;

&lt;p&gt;In JDK 26, teams are blindly migrating entire microservices to virtual threads and wondering why their p99 latency is suddenly spiking into the seconds. The culprit is carrier thread starvation: developers are treating lightweight virtual threads like silver bullets, forgetting that cooperative scheduling requires yield points that CPU-bound tasks simply do not have.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Most Developers Get This Wrong
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Treating virtual threads as "faster" threads&lt;/strong&gt; rather than "cheaper to block" threads. This leads to CPU-heavy operations (like JWT validation or heavy JSON parsing) being scheduled on the default &lt;code&gt;ForkJoinPool&lt;/code&gt; carrier pool, which is sized strictly to the number of available CPU cores.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Assuming the JVM will preemptively time-slice virtual threads.&lt;/strong&gt; In reality, Project Loom relies on cooperative scheduling, meaning a thread only yields during blocking I/O (e.g., socket reads, database queries, or explicit locks).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Running un-yieldable CPU tasks&lt;/strong&gt; that monopolize carrier threads, starving the other thousands of virtual threads waiting in the scheduler queue and completely halting the application's throughput.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Right Way
&lt;/h2&gt;

&lt;p&gt;Keep virtual threads strictly for I/O-bound operations and offload CPU-bound computations to a dedicated, sized platform thread pool.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Isolate CPU-heavy tasks&lt;/strong&gt; (e.g., BCrypt hashing, Jackson serialization of massive payloads, or complex cryptography) using a traditional &lt;code&gt;ThreadPoolExecutor&lt;/code&gt; sized strictly to the machine's physical cores.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bridge the gap using &lt;code&gt;CompletableFuture.supplyAsync()&lt;/code&gt;&lt;/strong&gt;, allowing the calling virtual thread to park cleanly and yield its carrier thread while the platform thread handles the heavy lifting.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Actively monitor carrier thread pinning&lt;/strong&gt; and starvation using JDK Flight Recorder (JFR) with the &lt;code&gt;jdk.VirtualThreadPinned&lt;/code&gt; event to identify blocking native calls or synchronized blocks.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Shameless plug: &lt;a href="https://javalld.com" rel="noopener noreferrer"&gt;javalld.com&lt;/a&gt; has full LLD implementations with step-by-step execution traces — free to use while prepping.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Show Me The Code (or Example)
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Inside a Virtual Thread handler&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;Response&lt;/span&gt; &lt;span class="nf"&gt;handleRequest&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Request&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// I/O bound: Fetch from DB (Virtual thread yields here)&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;findUser&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;userId&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt; 

    &lt;span class="c1"&gt;// CPU bound: Offload to prevent Carrier Thread Starvation&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;CompletableFuture&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;supplyAsync&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
        &lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;jwtService&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;generateToken&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt; &lt;span class="no"&gt;CPU_PLATFORM_POOL&lt;/span&gt;
    &lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;join&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Virtual thread yields cleanly while platform thread works&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Response&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Virtual threads are designed for waiting, not for burning CPU cycles.&lt;/li&gt;
&lt;li&gt;No yield point means carrier thread hijacking; keep &lt;code&gt;ForkJoinPool&lt;/code&gt; free.&lt;/li&gt;
&lt;li&gt;Always isolate CPU-bound tasks in a dedicated, sized platform &lt;code&gt;ThreadPoolExecutor&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>java</category>
      <category>concurrency</category>
      <category>systemdesign</category>
      <category>programming</category>
    </item>
    <item>
      <title>Java LLD: Designing a Thread-Safe Parking Lot with Strategy Pattern</title>
      <dc:creator>Machine coding Master</dc:creator>
      <pubDate>Fri, 29 May 2026 06:41:47 +0000</pubDate>
      <link>https://dev.to/machinecodingmaster/java-lld-designing-a-thread-safe-parking-lot-with-strategy-pattern-b7g</link>
      <guid>https://dev.to/machinecodingmaster/java-lld-designing-a-thread-safe-parking-lot-with-strategy-pattern-b7g</guid>
      <description>&lt;h2&gt;
  
  
  Java LLD: Designing a Thread-Safe Parking Lot with Strategy Pattern
&lt;/h2&gt;

&lt;p&gt;Designing a parking lot is a staple of Java LLD and machine coding interviews, yet most candidates fail to write production-grade code. As an ex-FAANG interviewer, I've seen countless designs fall apart under concurrent traffic or when asked to support multiple slot allocation algorithms.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you're prepping for interviews, I've been building &lt;a href="https://javalld.com" rel="noopener noreferrer"&gt;javalld.com&lt;/a&gt; — real machine coding problems with full execution traces.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  The Mistake Most Candidates Make
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Monolithic locking on the entire &lt;code&gt;ParkingLot&lt;/code&gt; class:&lt;/strong&gt; Using a global &lt;code&gt;synchronized&lt;/code&gt; keyword on the entry method, which serializes all gate entries and destroys system throughput.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hardcoding slot-finding logic:&lt;/strong&gt; Mixing spatial layout algorithms (like nearest-to-entrance or smallest-available-fit) directly inside the &lt;code&gt;ParkingLot&lt;/code&gt; or &lt;code&gt;Gate&lt;/code&gt; classes, violating the Open-Closed Principle.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Thread-safety as an afterthought:&lt;/strong&gt; Relying on raw &lt;code&gt;List&amp;lt;Slot&amp;gt;&lt;/code&gt; iterations without synchronization, causing race conditions where multiple cars are assigned to the exact same physical slot.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Right Approach
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Core mental model:&lt;/strong&gt; Decouple capacity management from slot selection by using a &lt;code&gt;Semaphore&lt;/code&gt; for gate-keeping and the Strategy Pattern for thread-safe slot allocation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Key entities:&lt;/strong&gt; &lt;code&gt;ParkingLot&lt;/code&gt;, &lt;code&gt;Gate&lt;/code&gt;, &lt;code&gt;Slot&lt;/code&gt;, &lt;code&gt;Vehicle&lt;/code&gt;, &lt;code&gt;ParkingStrategy&lt;/code&gt; (&lt;code&gt;SmallestFitStrategy&lt;/code&gt;, &lt;code&gt;NearestEntranceStrategy&lt;/code&gt;), and &lt;code&gt;StrategyFactory&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Why it beats the naive approach:&lt;/strong&gt; It isolates concurrency concerns (preventing overbooking) from business rules (how we choose a slot), making the system highly performant and easily extensible.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Key Insight (Code)
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;EntryGate&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Semaphore&lt;/span&gt; &lt;span class="n"&gt;semaphore&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;ParkingStrategy&lt;/span&gt; &lt;span class="n"&gt;strategy&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;EntryGate&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;capacity&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;ParkingStrategy&lt;/span&gt; &lt;span class="n"&gt;strategy&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;semaphore&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Semaphore&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;capacity&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;strategy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;strategy&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;synchronized&lt;/span&gt; &lt;span class="nc"&gt;Ticket&lt;/span&gt; &lt;span class="nf"&gt;park&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Vehicle&lt;/span&gt; &lt;span class="n"&gt;vehicle&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(!&lt;/span&gt;&lt;span class="n"&gt;semaphore&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;tryAcquire&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ParkingFullException&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="nc"&gt;Slot&lt;/span&gt; &lt;span class="n"&gt;slot&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;strategy&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;allocateSlot&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vehicle&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;slot&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;occupy&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vehicle&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Ticket&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vehicle&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;slot&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Throttle Early with Semaphores:&lt;/strong&gt; Use a &lt;code&gt;Semaphore&lt;/code&gt; at the gate level to reject incoming cars instantly when the lot is full, avoiding expensive database or memory lock lookups.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Strategy Pattern for Allocation:&lt;/strong&gt; Encapsulate slot-finding algorithms in a &lt;code&gt;ParkingStrategy&lt;/code&gt; interface, allowing the system to switch behaviors dynamically at runtime.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Factory Pattern for Instantiation:&lt;/strong&gt; Leverage a &lt;code&gt;StrategyFactory&lt;/code&gt; to cleanly instantiate the correct allocation strategy based on the parking lot's operating mode.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Full working implementation with execution trace available at &lt;a href="https://javalld.com/problems/parking-lot" rel="noopener noreferrer"&gt;https://javalld.com/problems/parking-lot&lt;/a&gt;&lt;/p&gt;

</description>
      <category>java</category>
      <category>systemdesign</category>
      <category>oop</category>
      <category>concurrency</category>
    </item>
    <item>
      <title>Java &amp; AI: What Developers Need to Know</title>
      <dc:creator>Machine coding Master</dc:creator>
      <pubDate>Thu, 28 May 2026 06:37:58 +0000</pubDate>
      <link>https://dev.to/machinecodingmaster/java-ai-what-developers-need-to-know-53eg</link>
      <guid>https://dev.to/machinecodingmaster/java-ai-what-developers-need-to-know-53eg</guid>
      <description>&lt;h2&gt;
  
  
  Java LLD: High-Concurrency Ticket Booking System (BookMyShow)
&lt;/h2&gt;

&lt;p&gt;Designing BookMyShow is a classic LLD interview favorite because it tests your ability to handle high concurrency without sacrificing data consistency. If you cannot explain how to prevent two users from booking the exact same seat simultaneously under heavy load, your system design interview is over.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Mistake Most Candidates Make
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Global Database Locks:&lt;/strong&gt; Using heavy database-level row locks (&lt;code&gt;SELECT ... FOR UPDATE&lt;/code&gt;) which drastically reduces throughput during peak ticket sales.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Linear Seat Scanning:&lt;/strong&gt; Utilizing basic arrays or lists to search for contiguous seat allocations, resulting in slow $O(N)$ query times.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Naïve Synchronization:&lt;/strong&gt; Synchronizing the entire booking method block, which bottlenecks the entire system and prevents concurrent bookings across different theaters.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Right Approach
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Core mental model:&lt;/strong&gt; Isolate seat contention per show using in-memory semaphores, while managing contiguous seat boundaries using an Interval Tree.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Key entities/classes:&lt;/strong&gt; &lt;code&gt;Show&lt;/code&gt;, &lt;code&gt;Seat&lt;/code&gt;, &lt;code&gt;ShowSeatManager&lt;/code&gt;, &lt;code&gt;IntervalTree&lt;/code&gt;, &lt;code&gt;Booking&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Why it beats the naive approach:&lt;/strong&gt; It localizes lock contention to individual shows instead of the entire database, enabling millions of concurrent users to book different shows simultaneously.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Shameless plug: &lt;a href="https://javalld.com" rel="noopener noreferrer"&gt;javalld.com&lt;/a&gt; has full LLD implementations with step-by-step execution traces — free to use while prepping.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  The Key Insight (Code)
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ShowSeatManager&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Semaphore&lt;/span&gt; &lt;span class="n"&gt;showLock&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Semaphore&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Isolate lock per show&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;IntervalTree&lt;/span&gt; &lt;span class="n"&gt;bookedSeats&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;IntervalTree&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt; 

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="nf"&gt;reserveSeats&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(!&lt;/span&gt;&lt;span class="n"&gt;showLock&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;tryAcquire&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Fail fast under heavy load&lt;/span&gt;
        &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bookedSeats&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;hasOverlap&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Already booked&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;
            &lt;span class="n"&gt;bookedSeats&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;insert&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;finally&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;showLock&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;release&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Thread Confinement via Semaphores:&lt;/strong&gt; Use a dedicated &lt;code&gt;Semaphore&lt;/code&gt; per show to localize concurrency, ensuring that high demand for a blockbuster movie doesn't block bookings for other shows.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Interval Tree for Range Queries:&lt;/strong&gt; Optimize contiguous seat selection; checking if a range of seats (e.g., seats 10 to 15) is available drops from $O(N)$ to $O(\log N)$ complexity.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Optimistic Locking Safety Net:&lt;/strong&gt; Pair your in-memory locks with database optimistic locking (&lt;code&gt;@Version&lt;/code&gt;) as a final line of defense to guarantee zero double-bookings.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Full working implementation with execution trace available at &lt;a href="https://javalld.com/problems/bookmyshow" rel="noopener noreferrer"&gt;https://javalld.com/problems/bookmyshow&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;---JSON&lt;br&gt;
{&lt;br&gt;
  "title": "Java LLD: High-Concurrency Ticket Booking System (BookMyShow)",&lt;br&gt;
  "tags": ["java", "design", "concurrency", "systemdesign"]&lt;br&gt;
}&lt;br&gt;
---END---&lt;/p&gt;

</description>
      <category>java</category>
      <category>programming</category>
      <category>ai</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Why Your eBPF Profiler Lies to You About Java Virtual Threads</title>
      <dc:creator>Machine coding Master</dc:creator>
      <pubDate>Wed, 27 May 2026 06:47:01 +0000</pubDate>
      <link>https://dev.to/machinecodingmaster/why-your-ebpf-profiler-lies-to-you-about-java-virtual-threads-ikf</link>
      <guid>https://dev.to/machinecodingmaster/why-your-ebpf-profiler-lies-to-you-about-java-virtual-threads-ikf</guid>
      <description>&lt;h2&gt;
  
  
  Why Your eBPF Profiler Lies to You About Java Virtual Threads
&lt;/h2&gt;

&lt;p&gt;In 2026, virtual threads are the default concurrency model in Java, but your production profiling is likely still blind to what is actually happening at the OS level. Traditional eBPF profilers see carrier threads (&lt;code&gt;ForkJoinPool-1-worker-*&lt;/code&gt;), completely missing the ephemeral virtual threads (&lt;code&gt;VirtualThread&lt;/code&gt;) mounted on them during system-level blocks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Most Developers Get This Wrong
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Trusting legacy APM agents:&lt;/strong&gt; Relying on standard JVM TI (Tooling Interface) agents that introduce massive safepoint overhead and fail under the sheer volume of millions of virtual threads.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ignoring the Carrier Thread abstraction:&lt;/strong&gt; Assuming OS-level CPU usage maps 1:1 to your business logic, when in reality, the kernel only sees the carrier thread, hiding virtual thread pinning and starvation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Failing to correlate thread IDs:&lt;/strong&gt; Thinking &lt;code&gt;Thread.currentThread().threadId()&lt;/code&gt; matches the kernel TID, which breaks down entirely when virtual threads are multiplexed.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Right Way
&lt;/h2&gt;

&lt;p&gt;To achieve zero-overhead continuous profiling, you must stitch kernel-space eBPF stack traces with user-space Loom state by tracking virtual thread mounting and unmounting events in the JVM.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Leverage JVM USDT (Userland Statically Defined Tracing) Probes:&lt;/strong&gt; Tap into internal JVM transition events to capture when a virtual thread mounts or unmounts from a carrier thread.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Maintain a BPF Map for Context:&lt;/strong&gt; Use a shared eBPF map keyed by the OS Thread ID (TID) to store the active &lt;code&gt;java.lang.VirtualThread&lt;/code&gt; object address or correlation ID.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stitch Stacks JIT-Side:&lt;/strong&gt; Correlate the kernel stack (retrieved via &lt;code&gt;bpf_get_stackid&lt;/code&gt;) with the JVM frame pointer stack at the exact moment of the OS-level block (e.g., &lt;code&gt;sys_enter_epoll_wait&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Shameless plug: &lt;a href="https://javalld.com" rel="noopener noreferrer"&gt;javalld.com&lt;/a&gt; has full LLD implementations with step-by-step execution traces — free to use while prepping.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Show Me The Code (or Example)
&lt;/h2&gt;

&lt;p&gt;The following eBPF C snippet intercepts JVM virtual thread mount events to map the OS carrier thread to the active logical virtual thread ID:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="c1"&gt;// eBPF map tracking: Carrier TID -&amp;gt; Virtual Thread ID&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;__uint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;BPF_MAP_TYPE_HASH&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;__type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;u32&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Carrier Thread TID&lt;/span&gt;
    &lt;span class="n"&gt;__type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;u64&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Virtual Thread ID Address&lt;/span&gt;
    &lt;span class="n"&gt;__uint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_entries&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;32768&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;vthread_map&lt;/span&gt; &lt;span class="nf"&gt;SEC&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;".maps"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;SEC&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"uprobe/libjvm/virtual_thread_mount"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;handle_vthread_mount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;pt_regs&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;u32&lt;/span&gt; &lt;span class="n"&gt;carrier_tid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bpf_get_current_pid_tgid&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;u64&lt;/span&gt; &lt;span class="n"&gt;vthread_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PT_REGS_PARM1&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Read vthread object reference&lt;/span&gt;
    &lt;span class="n"&gt;bpf_map_update_elem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;vthread_map&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;carrier_tid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;vthread_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;BPF_ANY&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Stop relying on old-school Thread Locals:&lt;/strong&gt; Virtual threads hop across carrier threads; your profiling context must be dynamically mapped via eBPF.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;USDT is your bridge:&lt;/strong&gt; Use JVM's internal tracing points to update eBPF maps in real-time with zero JVM-side overhead.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stitch, don't guess:&lt;/strong&gt; True observability in 2026 requires merging physical kernel-level execution with logical virtual-thread lifecycles.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>java</category>
      <category>concurrency</category>
      <category>systemdesign</category>
      <category>computerscience</category>
    </item>
    <item>
      <title>Java 26 Structured Concurrency: Stop Subclassing StructuredTaskScope and Use JEP 480 Joiners</title>
      <dc:creator>Machine coding Master</dc:creator>
      <pubDate>Tue, 26 May 2026 06:32:05 +0000</pubDate>
      <link>https://dev.to/machinecodingmaster/java-26-structured-concurrency-stop-subclassing-structuredtaskscope-and-use-jep-480-joiners-1ibf</link>
      <guid>https://dev.to/machinecodingmaster/java-26-structured-concurrency-stop-subclassing-structuredtaskscope-and-use-jep-480-joiners-1ibf</guid>
      <description>&lt;h2&gt;
  
  
  Java 26 Structured Concurrency: Stop Subclassing StructuredTaskScope and Use JEP 480 Joiners
&lt;/h2&gt;

&lt;p&gt;With Java 26 finalizing Structured Concurrency under JEP 480, it's time to delete your legacy preview code that subclasses &lt;code&gt;StructuredTaskScope&lt;/code&gt;. The era of extending this class for custom gather-scatter policies is officially over, replaced by a much cleaner, composition-first &lt;code&gt;Joiner&lt;/code&gt; API.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Most Developers Get This Wrong
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cargo-culting outdated tutorials:&lt;/strong&gt; Many developers are still copying early preview examples that forced you to subclass &lt;code&gt;StructuredTaskScope&lt;/code&gt; (like creating custom variants of &lt;code&gt;ShutdownOnFailure&lt;/code&gt;) just to implement custom result aggregation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Brittle inheritance:&lt;/strong&gt; Writing stateful subclasses of &lt;code&gt;StructuredTaskScope&lt;/code&gt; violates basic OOP composition principles and introduces unnecessary thread-safety risks when coordinating virtual threads.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ignoring the deprecation path:&lt;/strong&gt; Failing to realize that subclassing is now an anti-pattern; the engine class is designed to be configured via composition, not extended.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Right Way
&lt;/h2&gt;

&lt;p&gt;Shift from inheritance to composition by leveraging the new &lt;code&gt;StructuredTaskScope.Joiner&lt;/code&gt; interface to inject custom aggregation and short-circuiting logic directly into the scope.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Instantiate scopes exclusively using the new static factory &lt;code&gt;StructuredTaskScope.open(Joiner)&lt;/code&gt; instead of extending the class.&lt;/li&gt;
&lt;li&gt;Implement custom policies by writing a lightweight &lt;code&gt;Joiner&lt;/code&gt; that handles task results via &lt;code&gt;onFork&lt;/code&gt; and determines when to wake the owner thread via &lt;code&gt;onComplete&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Keep your concurrency coordination completely stateless, reusable, and decoupled from the lifecycle of the virtual threads themselves.&lt;/li&gt;
&lt;li&gt;Leverage the built-in factory methods like &lt;code&gt;Joiner.allSuccessful()&lt;/code&gt; or &lt;code&gt;Joiner.anySuccessful()&lt;/code&gt; for standard patterns before writing custom implementations.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Show Me The Code
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Java 26 composition: Pass a Joiner directly to the scope&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;joiner&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;StructuredTaskScope&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Joiner&lt;/span&gt;&lt;span class="o"&gt;.&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;allSuccessful&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt; 
&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;scope&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;StructuredTaskScope&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;open&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;joiner&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;task1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;scope&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;fork&lt;/span&gt;&lt;span class="o"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;fetchFromServiceA&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;task2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;scope&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;fork&lt;/span&gt;&lt;span class="o"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;fetchFromServiceB&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;

    &lt;span class="n"&gt;scope&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;join&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Blocks until joiner condition is met&lt;/span&gt;
    &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;scope&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;joiner&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;results&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Clean, type-safe composition&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Composition over Inheritance:&lt;/strong&gt; JEP 480 deprecates subclassing &lt;code&gt;StructuredTaskScope&lt;/code&gt;; always use &lt;code&gt;StructuredTaskScope.open(joiner)&lt;/code&gt; for modern virtual thread coordination.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Decoupled Policies:&lt;/strong&gt; Custom gather-scatter logic belongs in a &lt;code&gt;Joiner&lt;/code&gt; implementation, keeping your task coordination logic clean and unit-testable.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Future-Proof Concurrency:&lt;/strong&gt; Refactor your virtual thread code immediately to align with the finalized Java 26 standard before preview flags are dropped.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;If you're prepping for interviews, I've been building &lt;a href="https://javalld.com" rel="noopener noreferrer"&gt;javalld.com&lt;/a&gt; — real machine coding problems with full execution traces.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>java</category>
      <category>concurrency</category>
      <category>design</category>
      <category>programming</category>
    </item>
    <item>
      <title>Stop Polling Your Outbox: Lightweight Event Streaming with Postgres LISTEN/NOTIFY and Java Virtual Threads</title>
      <dc:creator>Machine coding Master</dc:creator>
      <pubDate>Mon, 25 May 2026 06:53:44 +0000</pubDate>
      <link>https://dev.to/machinecodingmaster/stop-polling-your-outbox-lightweight-event-streaming-with-postgres-listennotify-and-java-virtual-520j</link>
      <guid>https://dev.to/machinecodingmaster/stop-polling-your-outbox-lightweight-event-streaming-with-postgres-listennotify-and-java-virtual-520j</guid>
      <description>&lt;h2&gt;
  
  
  Stop Polling Your Outbox: Lightweight Event Streaming with Postgres LISTEN/NOTIFY and Java Virtual Threads
&lt;/h2&gt;

&lt;p&gt;For years, we’ve tolerated the operational headache of spinning up heavy Kafka Connect or Debezium clusters just to sync our transactional outbox tables. But in 2026, with Java's virtual threads fully mature and mainstream, blocking a database connection to wait on events is no longer an architectural sin—it's a massive simplification.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Most Developers Get This Wrong
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The Polling Tax:&lt;/strong&gt; Constantly querying &lt;code&gt;SELECT * FROM outbox WHERE status = 'PENDING' LIMIT 100&lt;/code&gt; shreds your database indexes, bloats transaction logs, and spikes CPU for no reason.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Over-Engineering with CDC:&lt;/strong&gt; Bootstrapping a complete Change Data Capture pipeline for a simple microservice boundary is operational overkill that introduces unnecessary network hops.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Thread Starvation Fears:&lt;/strong&gt; Developers still avoid blocking JDBC drivers like PostgreSQL's notification listener because they mistakenly think it will choke their thread pools.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Right Way
&lt;/h2&gt;

&lt;p&gt;Leverage PostgreSQL's native &lt;code&gt;LISTEN/NOTIFY&lt;/code&gt; system bound directly to a dedicated Java virtual thread that blocks cheaply and reacts instantly.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Virtual Thread Per Listener:&lt;/strong&gt; Spawn an unpinned virtual thread using &lt;code&gt;Thread.ofVirtual().start()&lt;/code&gt; to run a blocking &lt;code&gt;getNotifications()&lt;/code&gt; loop.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Database Triggers:&lt;/strong&gt; Use a lightweight Postgres trigger on your &lt;code&gt;outbox&lt;/code&gt; table to automatically execute &lt;code&gt;NOTIFY outbox_channel, payload&lt;/code&gt; on insert.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Zero-Overhead Parsing:&lt;/strong&gt; Read the notification payload directly in Java, deserialize it, and dispatch it to your event broker instantly.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Show Me The Code
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Executed inside Thread.ofVirtual().start(...)&lt;/span&gt;
&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dataSource&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getConnection&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pgConn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;unwrap&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;PGConnection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;createStatement&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;execute&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"LISTEN outbox_channel"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="o"&gt;(!&lt;/span&gt;&lt;span class="nc"&gt;Thread&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;currentThread&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;isInterrupted&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Blocks cheaply on a virtual thread, yielding the carrier thread&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;notifications&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pgConn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getNotifications&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10000&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;notifications&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;notification&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;notifications&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;eventPublisher&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;publish&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;notification&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getParameter&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;SQLException&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Listener failed"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Drop CDC Overhead:&lt;/strong&gt; You don't need Debezium or Kafka Connect for simple transactional outbox patterns anymore.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Zero Polling Latency:&lt;/strong&gt; Events are pushed immediately from Postgres to your Java application via TCP, cutting latency to sub-millisecond.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Infinite Scale on JVM:&lt;/strong&gt; Because Virtual Threads are virtually free, you can run hundreds of dedicated listeners without exhausting the OS thread pool.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Want to go deeper? &lt;a href="https://javalld.com" rel="noopener noreferrer"&gt;javalld.com&lt;/a&gt; — machine coding interview problems with working Java code and full execution traces.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>java</category>
      <category>systemdesign</category>
      <category>concurrency</category>
      <category>design</category>
    </item>
  </channel>
</rss>
