Part 03:
1. Why multithreading matters in backend
● A backend server handles many requests at the same time.
● Each request may query DB, call another API, or process data.
● If you used one thread only → the server would block and crawl.
● Multithreading = parallelism + concurrency:
○ Parallelism = doing multiple things at the same time (e.g., on multiple CPU cores).
○ Concurrency = managing multiple tasks that overlap in time (e.g., while waiting for DB, handle
another request).
2. Core Concepts
Threads
● Smallest unit of execution.
● Old way: manually create and start threads. Rarely used in real backend projects.
Executors
● Framework for managing pools of threads.
● You don’t create threads directly; you submit tasks to an executor.
● Makes thread management efficient and scalable.
Futures
● A placeholder object for a result that will be available later.
● You can wait for the result (blocking).
● Limitation: hard to combine or chain multiple asynchronous tasks.
CompletableFuture
● Modern async tool.
● Lets you chain tasks, combine results, handle errors, all without blocking.
● Perfect for backend when you need to call multiple services or DBs in parallel.
Parallel Streams
● Shortcut to process collections or ranges of data using multiple CPU cores automatically.
● Useful for CPU-heavy operations (like data crunching).
● Not ideal for I/O-bound tasks (like API calls or DB queries).
3. Concurrency Utilities
Java provides specialized tools for safe, coordinated multi-threaded work:
● ConcurrentHashMap → thread-safe map.
● BlockingQueue → classic producer-consumer pattern.
● CountDownLatch → wait for a group of tasks to complete.
● Semaphore → limit the number of concurrent tasks.
● Locks (ReentrantLock, StampedLock, etc.) → advanced control beyond synchronized.
4. Common Concurrency Problems
● Race Condition → two threads update the same resource without coordination → inconsistent results.
● Deadlock → two threads wait on each other’s locks → system freezes.
● Starvation → some tasks never get CPU time because others hog the pool.
5. Backend Reality Check
● Each HTTP request is usually handled on a thread.
● If the thread is blocked by a database query or API call, it can’t serve another request.
● With async programming (CompletableFuture or reactive frameworks like WebFlux), the thread is freed
while waiting, so the server handles more requests with fewer threads.
● General rule:
○ Use thread pools / parallel streams for CPU-heavy tasks.
○ Use async APIs for I/O-heavy tasks.