#Post9 In last post(https://lnkd.in/ddzdPfvQ), we learned about selecting optimal number of threads for our process. Common assumption is, a thread is either running or not. In reality, a thread spends most of its life NOT running. To understand multithreading properly, we need to understand the lifecycle of a thread. Let’s break it down. 1. New A thread is created but not started yet. Thread t = new Thread(); At this point, it’s just an object in memory. 2. Runnable Once you call start(), the thread becomes ready to run. It doesn’t mean it is running immediately. It simply means it is waiting for CPU scheduling. 3. Running When the CPU scheduler picks the thread, it starts executing. This is the state where actual work happens. 4. Blocked A thread enters this state when it is trying to acquire a lock, but another thread already holds it. Until the lock is released, the thread cannot proceed. 5. Waiting A thread goes into this state when wait() is called. • It pauses execution indefinitely • Releases the monitor lock • Becomes runnable again only after notify() or notifyAll() 6. Timed Waiting A thread waits for a specific amount of time. Examples: • sleep() • join() • wait(timeout) Important detail: • sleep() does NOT release the lock • wait(timeout) releases the lock 7. Terminated The thread has finished execution. Once terminated, it cannot be started again. Below is a reference diagram of the thread lifecycle. We will revisit this as we go deeper into concepts like start(), wait(), and synchronization Key takeaway A thread is not constantly running. In real systems, most threads are: • Waiting • Blocked • Or ready to run Understanding this helps build the foundation for: • Debugging concurrency issues • Avoiding deadlocks • Writing efficient multithreaded code In the next post, we will look at different ways to create threads in Java. #Java #Multithreading #Concurrency #BackendDevelopment #SoftwareEngineering
Thread Lifecycle: New Runnable Running Blocked Waiting Terminated
More Relevant Posts
-
When a system creates too many threads for small tasks, it can waste CPU and memory resources. Day 23 of my Low Level Design journey. Today I learned about Thread Pools and Executors in Java. Instead of creating a new thread for every task, a Thread Pool reuses a fixed number of threads to execute tasks efficiently. I learned about: • execute(Runnable) → Fire and forget tasks • submit(Runnable/Callable) → Returns Future to track task status • newFixedThreadPool() • newCachedThreadPool() • newSingleThreadExecutor() This approach helps in: • Better resource management • Improved performance • Controlled thread creation • Scalable concurrent systems Key takeaway: Thread Pool manages threads, while Executor manages task execution. Day 23 ✅ #LearningInPublic #LowLevelDesign #Multithreading #Concurrency #Java #SystemDesign #SoftwareEngineering #TakeUForward
To view or add a comment, sign in
-
-
Last week, we faced a critical production issue that reminded me how tricky multithreading can be in Java. 🔍 Problem: Our application suddenly became slow under load. CPU usage was low, but requests were timing out. 🧠 Root Cause: After analyzing thread dumps using tools like jstack and VisualVM, we discovered a classic deadlock situation. Two threads were waiting on each other’s locks — and nothing was moving forward. ⚠️ Key Learnings: Always maintain a consistent lock ordering to avoid deadlocks Avoid excessive use of synchronized blocks Prefer high-level concurrency utilities like ExecutorService, ReentrantLock, and ConcurrentHashMap Monitor thread pools in production (size, queue, rejection policy) Use tools like jconsole, VisualVM, and thread dumps regularly 💡 Pro Tip: Multithreading issues rarely appear in development — they show up under real traffic. Always design with concurrency in mind. 👨💻 As developers, writing correct concurrent code is not just a skill — it's a responsibility. #Java #Multithreading #BackendDevelopment #ProductionIssues #SoftwareEngineering #Debugging #TechLearning
To view or add a comment, sign in
-
𝐓𝐡𝐫𝐞𝐚𝐝 𝐒𝐚𝐟𝐞𝐭𝐲 - 𝐭𝐡𝐞 𝐛𝐮𝐠 𝐭𝐡𝐚𝐭 𝐥𝐢𝐞𝐬 𝐪𝐮𝐢𝐞𝐭𝐥𝐲 𝐮𝐧𝐭𝐢𝐥 𝐩𝐞𝐚𝐤 𝐭𝐫𝐚𝐟𝐟𝐢𝐜. Multiple threads sharing the same memory is powerful. It is also dangerous. 𝐖𝐡𝐚𝐭 𝐢𝐬 𝐢𝐭? When two threads read and write the same variable at the same time the result becomes unpredictable. This is called a Race Condition. No crash. No exception. Just silently wrong results. A payment processed twice. A counter off by thousands. A balance that never adds up. 𝐖𝐡𝐞𝐧 𝐝𝐨𝐞𝐬 𝐢𝐭 𝐡𝐚𝐩𝐩𝐞𝐧? → Shared counters updated by multiple threads → Shared collections read and written simultaneously → Singleton beans with mutable state in Spring → Cached values updated without synchronization 𝐇𝐨𝐰 𝐭𝐨 𝐩𝐫𝐞𝐯𝐞𝐧𝐭 𝐢𝐭? → Use Atomic types for simple counters and flags → Use immutable objects wherever possible → Use thread-safe collections like ConcurrentHashMap → Avoid shared mutable state entirely when you can → Scope variables locally - local variables are always safe 𝐓𝐡𝐞 𝐦𝐢𝐧𝐝𝐬𝐞𝐭 𝐬𝐡𝐢𝐟𝐭: Stop asking "does this work?" Start asking "what happens when 1000 threads hit this simultaneously?" Thread safety bugs don't show in unit tests. They show in production at the worst possible moment. #Java #ThreadSafety #Concurrency #RaceCondition #BackendEngineering
To view or add a comment, sign in
-
I once thought creating threads = better performance. I was wrong. 👉 Problem: Creating too many threads in a backend system can actually slow everything down. ❌ What goes wrong? High memory usage Too much context switching CPU spends more time managing threads than doing work 👉 So what’s the better approach? ✅ Use Thread Pools (ExecutorService) Instead of creating new threads every time: ✔️ Reuse existing threads ✔️ Control concurrency ✔️ Improve performance & stability 🧠 Real-world usage: Handling API requests Processing background jobs Managing async tasks 💡 Example: Executors.newFixedThreadPool(10) → Limits system to 10 threads handling tasks efficiently 💬 Curious: Have you ever faced performance issues due to too many threads? #Java #Multithreading #Backend #SystemDesign #Microservices #LearningInPublic
To view or add a comment, sign in
-
I once crashed a production system… because of multithreading. Everything was working fine in testing. But in production? 💥 Random failures. High CPU. Threads stuck. The issue? 👉 Poor multithreading design. That day, I learned something important: Multithreading is powerful… but dangerous if you don’t respect it. here are the best practices, limitations, and common mistakes I have learned 👇 Lesson 1: Threads are not free Earlier, I used to create multiple threads thinking "more threads = more performance" Reality: ❌ Context switching overhead ❌ Memory issues ✅ Now: I use Virtual Threads (Java 21) Lightweight. Scalable. Game changer. 👉 Example: Executors.newVirtualThreadPerTaskExecutor() Lesson 2: Shared state is the real enemy I had multiple threads updating the same object… Result? 👉 Race conditions 👉 Inconsistent data ✅ Now: Prefer immutable objects Use thread-safe collections Lesson 3: Synchronization can kill performance At one point, I added synchronized everywhere just to be safe. Bad idea. System became slow 🐌 ✅ Now: Use locks carefully (ReentrantLock) Prefer non-blocking approaches, ReadWriteLock Lesson 4: Exceptions in threads are silent killers One bug took hours to debug… Because exception was thrown inside a thread and never logged. ✅ Now: Always handle exceptions (CompletableFuture) Add proper logging Lesson 5. Monitor & Tune Thread Pools Unmonitored threads = production issues. ✅ Use: Micrometer + Prometheus + Grafana Thread pool metrics JVM monitoring tools 🔥 Golden Rules (Do’s & Don’ts) ✅ DO: Use Virtual Threads for scalability Keep tasks small & independent Use CompletableFuture for async flows Apply proper thread pool sizing ❌ DON’T: Block threads unnecessarily Share mutable state Create threads manually Ignore observability #Java #SpringBoot #Multithreading #Java21 #BackendDevelopment #Microservices #Concurrency #SoftwareEngineering #TechLeadership
To view or add a comment, sign in
-
-
#day22 ⚙️ Thread Pool Tuning — from working code to production-ready systems Thread pools are powerful — but only if tuned correctly 💡 👉 Key factors: corePoolSize maxPoolSize queue type rejection policy Example 👇 ThreadPoolExecutor executor = new ThreadPoolExecutor( 4, 8, 60, TimeUnit.SECONDS, new ArrayBlockingQueue<>(100), new ThreadPoolExecutor.CallerRunsPolicy() ); 💡 Key insight: CPU-bound → threads = cores IO-bound → threads > cores 👉 Avoid unbounded queues — they can crash your system #Java #Multithreading #ThreadPool #Concurrency #JavaDeveloper #SystemDesign #InterviewPreparation #LearningInPublic
To view or add a comment, sign in
-
A multithreading mistake I’ve seen (and made) in backend systems: We increased threads from 50 → 200 expecting better throughput. CPU usage went up. Latency increased. Throughput stayed almost the same. The real bottleneck? • Database connection limits • Lock contention • Context switching overhead More threads didn’t solve the problem. They amplified it. Concurrency improves performance only when your dependencies can handle the load. Threads don’t increase capacity. They expose your system’s weakest point. #Java #Multithreading #Concurrency #BackendEngineering #Performance #SystemDesign #DistributedSystems
To view or add a comment, sign in
-
More threads ≠ faster system. It often makes it slower. Most devs don’t realize this until production. 🔹 What actually happens ❌ Context switching increases ❌ Threads spend time waiting ❌ Memory overhead grows 👉 Result: performance drops 🔹 Quick Reality Check 👉 CPU-bound → threads ≈ cores 👉 IO-bound → slightly more threads Anything beyond that = diminishing returns 🔹 What about Virtual Threads? Java’s Virtual Threads (Project Loom): ✔ Lightweight ✔ Handle massive concurrency ✔ Reduce thread management overhead BUT 👇 👉 They don’t remove CPU limits 👉 Bad design will still hurt performance 🔹 Real Insight Multithreading is not about more threads It’s about right threads 🔹 Quick Interview Questions 1️⃣ What is context switching? 2️⃣ CPU-bound vs IO-bound? 3️⃣ How to decide optimal thread count ? 4️⃣ What are Virtual Threads? 5️⃣ Can more threads reduce performance? 🔹 Final Thought 👉 Platform threads need control 👉 Virtual threads need understanding 💬 Be honest: Are you overusing threads in your system? #Java #Multithreading #Performance #VirtualThreads #Backend
To view or add a comment, sign in
-
Day 65/100: Today I took another topic of LLD i.e. #Concurrency. Concurrency is nothing but dealing with multiple things at the same time. Every modern software system deals with concurrency. Your phone runs dozens of apps simultaneously. A web server handles thousands of requests at once. In Golang we can achieve concurrency using goroutines whereas in other programming languages like java we have multithreading concept for concurrency. When we talking about concurrency there is always confusion between concurrency and parallelism. Concurrency is about organizing code to handle many tasks in overlapping time periods. Parallelism involves performing multiple tasks at the same exact time, usually on different CPU cores. In concurrency we have to discover some important terms related to it. Race condition: A race condition occurs when the behavior of a program depends on the relative timing of events, such as the order in which threads are scheduled. When two or more threads access shared data concurrently, and at least one modifies it, the final result depends on who "wins the race" to access the data first. Deadlock: A deadlock is a state where a set of threads is blocked because each thread is holding a resource and waiting for a resource held by another thread in the set. Mutex: Mutex is a synchronization primitive that provides mutual exclusion. When a thread acquires (locks) a mutex, any other thread that tries to acquire the same mutex will block until the first thread releases (unlocks) it. The thread that locks must be the one to unlock. Concurrency Patterns: Thread Pool Pattern Producer-Consumer Pattern Fork-Join Pattern FanIn/out Pattern Time to do it again tomorrow :) #systemdesign #100daysofcode #softwareengineering #consistency
To view or add a comment, sign in
-
Over the Easter break I wrapped up my Operating Systems assignment for the master’s program: a Java CPU scheduling simulator (FCFS, non-preemptive SJF, SRTF, static priority, Round Robin), file-based input, metrics on the console, and a layered layout plus Strategy-style algorithms. Tests with JUnit/Mockito and Maven for the build. The repo stays private until the submission deadline (31 May); I’ll open it afterward for anyone who wants to browse the code. Project's gituhub: https://lnkd.in/dWHA4nyG Here's a spoiler of the chosen architecture design: #OperatingSystems #GradSchool #Masters #Java #UFMS #FACOM
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