api: YAML JSON TOON Database version: 1.0.0 format: json dataset: id: 38 slug: concurrency-design-patterns title: Concurrency Design Patterns description: "Patterns for multi-threaded programming: Producer-Consumer, Reader-Writer, Thread Pool, Future/Promise, Reactor, Monitor, Scheduler." summary: "Concurrency patterns for coordinating threads and tasks: producer-consumer, reader-writer locks, thread pools, futures and promises, the reactor pattern, monitors and schedulers, each with problem, solution, components, benefits, pitfalls and language examples." use_when[2]: You are structuring concurrent work and want a named solution.,You are reviewing code for concurrency pitfalls. caveats[2]: Concurrency bugs are timing dependent and hard to reproduce; prefer proven libraries.,"Many patterns are expressed differently in actor, async/await and channel-based languages." related[4]: concurrent-data-structures,go-concurrency-patterns,deadlock-handling,process-management category: Design Patterns category_slug: design-patterns tags: "design-patterns,concurrency,multithreading,producer-consumer,thread-pool" view_count: 0 created_at: 1777673262 updated_at: 1777673262 entry_count: 7 fields[7]{section,field,type,example}: patterns,name,string,Producer-Consumer (Bounded Buffer) patterns,problem,string,Producers generate data; consumers process it. … patterns,solution_brief,string,Use a fixed-size queue as buffer. Producers blo… patterns,key_components,array,"[4 items]" patterns,benefits,string,"Decouples producers and consumers, smooths load…" patterns,pitfalls,string,"Deadlock if synchronization incorrect, priority…" patterns,language_examples,object,"{Java,Python,C++,Go}" data: patterns[7]: - name: Producer-Consumer (Bounded Buffer) problem: "Producers generate data; consumers process it. Need to coordinate so consumers don't read from empty buffer, producers don't write to full buffer." solution_brief: Use a fixed-size queue as buffer. Producers block when full; consumers block when empty. Synchronized access ensures thread safety. key_components[4]: Shared buffer/queue with bounded capacity,"Producer threads (generate items, put in buffer)","Consumer threads (take items from buffer, process)",Synchronization mechanism (mutex + condition variables/semaphores) benefits: "Decouples producers and consumers, smooths load variations, enables pipelining, buffers spikes in production/consumption rates." pitfalls: "Deadlock if synchronization incorrect, priority inversion possible, buffer size tuning critical (too small causes blocking; too large uses memory), consumers may starve if producers fast." language_examples: Java: "BlockingQueue interface (ArrayBlockingQueue, LinkedBlockingQueue); put() and take() block automatically." Python: "queue.Queue (thread-safe), producer calls put(), consumer calls get()" "C++": "std::queue with std::mutex + std::condition_variable, or boost::lockfree::queue" Go: Channels (chan) with buffered or unbuffered; goroutines communicate naturally - name: Reader-Writer Lock problem: "Data structure frequently read, rarely written. Mutex allows only one thread at a time (even for readers), causing unnecessary contention." solution_brief: "Allow multiple readers simultaneous access, but writers get exclusive access. Readers don't block each other; writers block both readers and other writers." key_components[4]: "Read lock (shared): multiple threads can hold simultaneously","Write lock (exclusive): only one thread, no readers",Lock upgrade/downgrade (optional),Reader counter or reference count benefits: "Better throughput for read-heavy workloads, scales well with many readers, writers get exclusive access to prevent dirty reads." pitfalls: "Writer starvation if continuous readers arrive, reader-writer deadlock if not careful, higher overhead than simple mutex for write-heavy cases, complex to implement correctly." language_examples: Java: "java.util.concurrent.locks.ReentrantReadWriteLock; readLock().lock(), writeLock().lock()" "C++": "std::shared_mutex (C++17); std::shared_lock for readers, std::unique_lock for writers" Python: threading.RLock doesn't support readers; use read_write_lock third-party or multiprocessing.Manager "C#": "ReaderWriterLockSlim; EnterReadLock(), EnterWriteLock()" - name: Thread Pool problem: "Creating/destroying threads is expensive (OS resources, context switching). Spawning thread per task leads to overhead and uncontrolled resource usage." solution_brief: "Pre-create a fixed number of worker threads and queue tasks. Workers wait for tasks; when task arrives, idle worker executes it. Reuses threads across many tasks." key_components[4]: Thread pool (fixed size worker threads),"Task queue (work queue, blocking)","Worker loop: while (true) { task = queue.take(); execute(task); }","Saturation strategy (queue full: reject, block, or spawn new thread)" benefits: "Reduces thread creation overhead, bounds resource usage, improves response time (threads ready), enables task prioritization and scheduling." pitfalls: "Queue can become bottleneck, thread starvation if pool too small, deadlocks if tasks wait on other queued tasks, tasks may block pool threads indefinitely." language_examples: Java: "ExecutorService, ThreadPoolExecutor, Executors.newFixedThreadPool(n), CompletableFuture with custom executor" Python: "concurrent.futures.ThreadPoolExecutor, submit(task) returns Future" "C#": "Task Parallel Library (TPL), ThreadPool.QueueUserWorkItem, Task.Run" "C++": "Boost.Asio thread pool, Intel TBB task scheduler, custom with std::thread + std::queue" - name: Future / Promise problem: Need to run computation asynchronously and retrieve result later. Caller shouldn't block waiting for result; needs way to check completion or get result when ready. solution_brief: "Future is a placeholder for result of async operation. Promise is writeable handle that fulfills the future. Caller gets future immediately, checks isDone(), calls get() to block or poll." key_components[4]: "Future (read-only): isDone(), get(timeout), cancel()","Promise (write-only): setValue(result), setException(err)","Completion callback (optional): then(), addListener()",Cancellation mechanism benefits: "Avoids blocking threads, enables composition of async operations, simplifies error propagation, clean API for async results." pitfalls: "Blocking get() defeats purpose (use callbacks instead), exceptions must be captured in Future, cancellation not always supported, many small async tasks create overhead." language_examples: Java: "CompletableFuture (most powerful), Future (older), CompletableFuture.supplyAsync(...)" JavaScript: "Promise (then/catch), async/await syntactic sugar" Python: "concurrent.futures.Future, asyncio.Future" "C#": Task (Task is Future without result); async/await - name: Reactor Pattern problem: "Server handling many simultaneous connections (e.g., web server). One thread per connection (thread-per-connection) doesn't scale (thousands of connections = thousands of threads)." solution_brief: "Single (or few) thread(s) use non-blocking I/O and demultiplexer (select/poll/epoll/kqueue) to monitor multiple sockets. When I/O event occurs, dispatcher calls appropriate handler callback." key_components[4]: "Event demultiplexer (select, poll, epoll, kqueue)",Event handlers (callback objects),"Reactor (main loop: wait for events -> dispatch to handlers)",Non-blocking I/O sockets benefits: "Scales to thousands of connections with few threads, efficient resource usage (no thread overhead), good for I/O-bound services." pitfalls: "Complex to implement correctly, callbacks can lead to spaghetti code (use coroutines/fibers), CPU-bound tasks still block reactor, edge-triggered vs level-triggered pitfalls." language_examples: Java: "NIO (Non-blocking I/O), Selector, SocketChannel; Netty framework implements Reactor" Python: "selectors module, asyncio event loop, Twisted framework" Node.js: libuv event loop (epoll/kqueue/IOCP) built-in; all I/O non-blocking "C++": "Boost.Asio, libevent, libuv" - name: Monitor (Monitor Object) problem: Multiple threads access shared data; need to ensure mutual exclusion and coordinate access. Condition variables and mutexes scattered lead to error-prone code. solution_brief: Encapsulate shared data with its synchronization (mutex) and condition variables inside a monitor object. Only one thread can execute any monitor method at a time. Condition variables allow threads to wait for conditions. key_components[4]: Mutual exclusion lock (implicit in monitor entry),Condition variables (wait/signal),Shared data (private to monitor),Procedures/methods (only one active at a time) benefits: "Simplifies synchronization (acquire/release implicit), prevents unsynchronized access (all accesses go through monitor), high-level abstraction, reduces race conditions." pitfalls: "Can cause performance bottleneck if monitor too large (coarse-grained), conditional waiting can lead to missed signals or spurious wakeups, deadlocks possible if monitor calls external code." language_examples: Java: "synchronized methods/blocks (built-in monitor), wait()/notify()/notifyAll() on object" Python: "threading.Lock + Condition, but no built-in monitor keyword; can use with statement" "C#": "lock statement (Monitor.Enter/Exit), Monitor.Wait/Pulse" "C++": "No built-in monitor; implement with std::mutex + std::condition_variable" - name: Scheduler Pattern problem: "Need to execute tasks at specific times (cron jobs), at fixed intervals, or after delays. Managing timers and thread pools manually is complex." solution_brief: Central scheduler coordinates task execution based on time criteria. Maintains priority queue of scheduled tasks; scheduler thread manages timers and dispatches tasks to worker threads when due. key_components[5]: "Task (callable with execution time, priority, periodicity)",Schedule queue (priority queue ordered by next execution time),"Timer mechanism (wait/notify, delay queue, wheel timer)","Worker pool (optional, execute tasks asynchronously)","Scheduling strategies (fixed-rate, fixed-delay, cron)" benefits: "Centralized task management, efficient timer management (single thread for many timers), supports recurring tasks, cron-like scheduling, easy to pause/cancel/reschedule." pitfalls: "Scheduler thread single point of failure, task overruns can backlog, clock drift affects timing, distributed systems need distributed scheduler (e.g., Quartz, Celery)." language_examples: Java: "ScheduledExecutorService, Timer/TimerTask, Quartz Scheduler, Spring @Scheduled" Python: "sched module, APScheduler, Celery beat, cron jobs via OS" "C#": "System.Threading.Timer, Quartz.NET, Hangfire" Node.js: "node-cron, setInterval/setTimeout (single-threaded)"