Thread Models & I/O Multiplexing:
1. Synchronous (Blocking) Execution:
- Thread-per-request model (e.g., traditional Java/Ruby on Rails with thread pools).
- Execution Flow: When a thread initiates an I/O operation (database query, disk read, external API request), the thread is blocked, sitting idle while waiting for the network socket to return bytes.
- Limitations: Concurrency is strictly bounded by the operating system's thread limit (each OS thread consumes ~1MB stack memory). 10,000 concurrent requests require 10GB of memory, causing thrashing and context-switching overhead.
2. Asynchronous (Non-Blocking) Execution:
- Event-driven event loop model (Node.js, Go goroutines, Java Netty, Python asyncio).
- Execution Flow: I/O operations register a callback/promise and delegate to OS-level kernel multiplexing (epoll on Linux, kqueue on macOS) without blocking the thread. The thread remains free to process other incoming requests immediately.
- Advantages: Handles 100,000+ concurrent connections on minimal hardware memory.
- Disadvantages: CPU-bound tasks can block the event loop, requiring offloading to worker threads.