"Architecting Knowledge" - Java Wisdom Series Post #17: Virtual Threads - Rethinking Concurrency 👇 Million threads. One JVM. Welcome to Project Loom. Why This Matters: Platform threads map 1:1 to OS threads - each consumes ~1MB stack memory. You can create maybe 4000-10000 before your JVM dies. Virtual threads are JVM-managed and stack memory is allocated dynamically on heap - you can create millions. When a virtual thread blocks on I/O, the JVM unmounts it from its carrier thread (platform thread), letting that carrier run other virtual threads. This makes blocking I/O efficient again - no more callback hell. BUT beware thread pinning: synchronized blocks prevent unmounting in Java 21-23 (fixed in 24). Use ReentrantLock for long blocking operations. Key Takeaway: Virtual threads aren't faster - they're cheaper and more scalable. Perfect for I/O-bound workloads (web servers, microservices, API calls). Don't pool them, don't cache in ThreadLocal aggressively. Write simple blocking code, let Loom handle concurrency. #Java #JavaWisdom #VirtualThreads #ProjectLoom #Concurrency #Java21 Are you still using thread pools for I/O-bound tasks? Time to go virtual! All code examples on GitHub - bookmark for quick reference: https://lnkd.in/dJUx3Rd3
Mandar Pandit’s Post
More Relevant Posts
-
Continuing my recent posts on JVM internals and performance, today I’m sharing a look at Java 21 Virtual Threads (from Project Loom). For a long time, Java handled concurrency using platform threads (OS threads)—which are powerful but expensive, especially for I/O-heavy applications. This led to complex patterns like thread pools, async programming, and reactive frameworks to achieve scalability. With Virtual Threads, Java introduces a lightweight threading model where thousands (even millions) of threads can be managed efficiently. 👉 When a virtual thread performs a blocking I/O operation, the underlying carrier (platform) thread is released to do other work. This brings Java closer to the efficiency of event-loop models (like in Node.js), while still allowing developers to write simple, synchronous code without callback-heavy complexity. However, in real-world scenarios, especially when teams migrate from Java 8/11 to Java 21, it’s important to keep a few things in mind: • Virtual Threads are not a silver bullet—they primarily improve I/O-bound workloads, not CPU-bound ones • If the architecture is not aligned, you may not see significant latency improvements • Legacy codebases often contain synchronized blocks or locking, which can lead to thread pinning and reduce the benefits of Virtual Threads Project Loom took years to evolve because it required deep changes to the JVM, scheduling, and thread management—while preserving backward compatibility and Java’s simplicity. Sharing a diagram that illustrates: • Platform threads vs Virtual Threads • Carrier thread behavior • Pinning scenarios Curious to hear—are you exploring Virtual Threads in your applications, or still evaluating? 👇 #Java #Java21 #VirtualThreads #ProjectLoom #Concurrency #Performance #SoftwareEngineering
To view or add a comment, sign in
-
-
🚀 Java Memory Mastery: The String Constant Pool Ever wondered how Java handles millions of strings without crashing your memory? Meet the String Constant Pool (SCP)—the JVM's secret "unique-only" library. In this breakdown, I deconstruct the "Two-Object Trap": Literals ("Hello"): Check the pool. If it’s there, reuse it. Efficient and fast. The new Keyword: Forces a brand new object into the Heap, even if the text already exists. The Pro-Tip: Use .intern() to manually move Heap strings into the pool and keep your memory footprint lean. Stop duplicating data. Start optimizing your architecture. 🛠️ #Java #BackendEngineering #SystemDesign #JVM #SoftwareDevelopment #TheBytecodePhantom
To view or add a comment, sign in
-
-
🚀 Java 21 is not just another release — it’s a major leap for the Java ecosystem. What excites me most is that many features in Java 21 don’t just add syntax sugar — they solve real engineering problems we deal with in production. Some highlights from this release: ✅ Virtual Threads (JEP 444) Solves traditional thread scalability issues and makes high-concurrency applications much simpler. ✅ Structured Concurrency Makes parallel task management safer, cleaner and easier to reason about. ✅ Scoped Values A modern alternative to ThreadLocal with safer context propagation. ✅ Pattern Matching + Record Patterns Less boilerplate, cleaner domain modeling, more readable code. ✅ Sequenced Collections Small API improvement, big developer productivity gain. ✅ Generational ZGC Lower latency and better throughput for performance-sensitive systems. 💡 What I like most about Java 21: It improves three critical areas together: • Scalability • Developer Productivity • Enterprise Readiness For backend, microservices, cloud-native systems and high-throughput applications, this is a huge step forward. My take: Virtual Threads alone could reshape how many teams think about concurrency. Some are even asking: 👉 Will Virtual Threads reduce the need for complex reactive programming in some use cases? Curious what feature excites you most in Java 21? #Java21 #Java #OpenJDK #BackendDevelopment #SoftwareArchitecture #SpringBoot #Microservices #VirtualThreads #CloudNative #Programming #TechLeadership
To view or add a comment, sign in
-
-
🔥 Hot take: Thread pools are becoming legacy thinking in Java. For years, we’ve been juggling: → Limited thread pools → High memory usage → Complex async code And calling it “scalable” 😅 Then comes Java 21 + Virtual Threads (Project Loom)… ⚡ Thousands (even millions) of lightweight threads ⚡ Near-zero overhead ⚡ Write simple, blocking code — still scale like crazy No more over-engineering with reactive frameworks just to handle concurrency. Sometimes, the best innovation isn’t adding complexity… it’s removing it. If you haven’t explored Virtual Threads yet, now is the time. #Java21 #ProjectLoom #VirtualThreads #Concurrency #BackendDevelopment #SoftwareEngineering #TechTrends
To view or add a comment, sign in
-
-
🚀 Most Java developers think performance = better algorithms That’s incomplete. Real performance in Java often comes from what the JVM removes, not what you write. 👉 Escape Analysis (JVM optimization) The JVM checks whether an object “escapes” a method or thread. If it doesn’t, the JVM can: ✨ Allocate it on the stack (not heap) ✨ Remove synchronization (no locks needed) ✨ Eliminate the object entirely (scalar replacement) Yes — your object might never exist at runtime. 💡 Example: public void process() { User u = new User("A", 25); int age = u.getAge(); } If u never escapes this method, JVM can optimize it to: int age = 25; ❌ No object ❌ No GC pressure ❌ No overhead 📉 Where developers go wrong: • Creating unnecessary shared state • Overusing synchronization • Forcing objects onto the heap ✅ What you should do instead: • Keep objects local • Avoid unnecessary sharing between threads • Write code the JVM can optimize 🔥 Key Insight: Performance in Java isn’t just about writing efficient code. It’s about writing code the JVM can optimize. If you ignore this, you’re solving the wrong problem. #Java #JVM #Performance #SoftwareEngineering #BackendDevelopment
To view or add a comment, sign in
-
Virtual Threads in Java 21 for Scalable Backend Engineering. We dive into how Java 21’s Virtual Threads eliminate the complexity of traditional thread pools, letting you handle massive concurrency with simple, readable code, perfect for production AI and high-traffic backend systems. This is the kind of modern, performance-first upgrade every serious backend engineer needs in 2026. Watch the full clip below and comment: Have you started using Virtual Threads in your projects yet? Full Video: https://lnkd.in/e7rpe5q4 #Java21 #VirtualThreads #AIBackendEngineering #MasteringBackend
To view or add a comment, sign in
-
Go has no threads. Yet it handles 10x more concurrent requests than Java. Here is why that should change how you think about concurrency. When thousands of requests hit a server simultaneously, the biggest bottleneck is always the thread. Traditional languages like Java create one OS thread per request. Threads are heavy, kernel managed, and expensive to context switch. Go solved this differently with Goroutines. → A Goroutine's stack is dynamic. It only grows when it actually needs to, not upfront → Creating a Goroutine involves zero system calls. The kernel has no idea it exists → Context switching happens entirely in user space. No kernel involvement whatsoever → The Go scheduler handles everything. OS threads only see what Go exposes to them This is powered by the GMP model: → G: Goroutines, can run in the millions → M: Machine, the actual OS threads, just a handful → P: Processor, the logical CPU that schedules G onto M Millions of Goroutines multiplex across just a few OS threads. When a Goroutine blocks, Go detaches that thread, spins up work elsewhere, and keeps everything moving. The program never stalls. A Goroutine starts at just 2KB because Go's runtime manages memory dynamically instead of fixed provisioning like the OS does. This is not a language feature. It is an architectural decision. Minimize kernel involvement. Maximize work in user space. Let the runtime do what the OS was doing badly. That is the real reason Go scales the way it does. What architecture decision in your stack has had the biggest impact on performance? #GoLang #SystemDesign #BackendEngineering #Concurrency #BuildingInPublic #TechFounders #SoftwareArchitecture #Engineering #Programming #DevOps
To view or add a comment, sign in
-
🧠 JVM — The Brain of Java Everyone says “Java is platform independent”… But the real magic? It’s the JVM silently doing all the heavy lifting. Think of the JVM like the brain of your Java program — constantly thinking, optimizing, managing, and protecting. Here’s what’s happening behind the scenes: Class Loader Before anything runs, the JVM loads your .class files into memory. It’s like the brain gathering information before making decisions. Runtime Data Areas The JVM organizes memory like a well-structured mind: • Heap → where objects live • Stack → method calls & execution flow • Method Area → class-level data Everything has its place. No chaos. Just structure. Execution Engine This is where the real action happens. Bytecode is converted into machine code using an interpreter or optimized using JIT (Just-In-Time compiler). Translation: Your code gets faster the more it runs. Garbage Collector One of the smartest parts of the JVM. It automatically removes unused objects from memory. No manual cleanup. No memory leaks (mostly). Security & Isolation The JVM runs your code in a sandbox. That’s why Java is trusted for large-scale systems. Why this matters? When you understand the JVM, you stop just “writing code”… You start writing efficient, optimized systems. Because at the end of the day — Java doesn’t just run. The JVM thinks. #Java #JVM #BackendDevelopment #Programming #SoftwareEngineering #Tech
To view or add a comment, sign in
-
-
Stopping Threads Safely: Java does not allow killing a thread directly. Use interrupts as the “polite” way to request a thread to stop. Threads should check Thread.interrupted() or catch InterruptedException. Raw Threads vs Thread Pools With raw threads, you can interrupt them directly. With ThreadPool threads, you use ExecutorService.shutdown() or Future.cancel() to signal cancellation. Callable and Future: Wrapping tasks in Callable allows you to manage them with Future. Future.cancel(true) interrupts the task if it’s running. Useful for applying timeouts on long-running tasks. Volatile / AtomicBoolean Flags: Another approach is using a shared flag (volatile boolean stop = false;). The thread periodically checks this flag to decide whether to exit. AtomicBoolean provides thread-safe updates. Timeout Strategies: Use Thread.sleep() or scheduled tasks to enforce conditional timeouts. For blocking operations (DB calls, HTTP requests), combine interrupts with timeout-aware APIs. Example: future.get(timeout, TimeUnit.SECONDS). Practical Applications: Database Calls: Long stored procedures can be interrupted if they exceed SLA. HTTP Requests: Wrap in Future with timeout to avoid hanging threads. Schedulers: Cancel tasks after a fixed duration to maintain responsiveness. #Java #BackendDevelopment #SoftwareEngineering #MultiThreading #Concurrency #JavaPerformance #CodingTips #Programming #SystemDesign
To view or add a comment, sign in
Explore content categories
- Career
- Productivity
- Finance
- Soft Skills & Emotional Intelligence
- Project Management
- Education
- Technology
- Leadership
- Ecommerce
- User Experience
- Recruitment & HR
- Customer Experience
- Real Estate
- Marketing
- Sales
- Retail & Merchandising
- Science
- Supply Chain Management
- Future Of Work
- Consulting
- Writing
- Economics
- Artificial Intelligence
- Employee Experience
- Workplace Trends
- Fundraising
- Networking
- Corporate Social Responsibility
- Negotiation
- Communication
- Engineering
- Hospitality & Tourism
- Business Strategy
- Change Management
- Organizational Culture
- Design
- Innovation
- Event Planning
- Training & Development