Skip to main content

πŸ—“οΈ 27082025 2330
πŸ“Ž

java_concurrency_guidelines

Impact Levels​

Impact LevelMeaningExamples
🚨 CriticalMust fix immediately; could cause severe outages, data loss, or avalanchesUnbounded queues, inconsistent locks, ThreadLocal leaks
⚠️ HighShould fix promptly; could affect stability or performanceMissing Future timeouts, bad collection choice
🟒 AdvisoryBest practice; improves maintainability and efficiencyThread naming, Random vs ThreadLocalRandom

🧡 Thread Management​

GuidelineImpactWhy It Matters
Limit total threads to ≀ min(5000, 200 * CPU)⚠️ HighToo many threads β†’ context switching overhead + system jitter
Avoid parallel streams for I/O🚨 CriticalParallel streams share the ForkJoinPool β†’ I/O blocks all tasks, harming latency
Clean up ThreadLocal variables after use🚨 CriticalThread pools reuse threads β†’ stale data leaks + unexpected cross-request contamination
Always handle CompletableFuture exceptions⚠️ HighUncaught exceptions are silently dropped β†’ makes debugging difficult
Use custom thread pools for CompletableFuture🚨 CriticalDefault pool = small, shared β†’ risk of starvation or excessive thread creation
Set timeouts on Future.get()⚠️ HighWithout timeouts, a blocked future can hang threads indefinitely

πŸŠβ€β™€οΈ Thread Pool Best Practices​

GuidelineImpactWhy It Matters
Core threads β‰ˆ max threads🟒 AdvisoryAvoids frequent creation/destruction > better latency and CPU usage
Keep-alive β‰₯ 1 min⚠️ High if < 30s, 🚨 Critical if < 10sShort lifetimes thrash thread creation, increasing CPU spikes
Avoid unbounded queues🚨 CriticalTasks pile up > unbounded memory growth > OOM risk
Specify custom pools for @Async🚨 CriticalDefault Spring async pool is unbounded > uncontrolled thread growth
Specify custom pools for WebAsyncTask / DeferredResult🚨 CriticalDefaults to shared pool > contention under high traffic
Name threads meaningfully🟒 AdvisoryHelps debugging via jstack and log tracing

πŸ›‘οΈ Thread Safety Guidelines​

GuidelineImpactWhy It Matters
Use proper double-checked locking🚨 CriticalIncorrect ordering β†’ partially initialized objects β†’ undefined behavior
Don’t start threads in constructors⚠️ HighThreads may run before subclass initialization β†’ inconsistent state
Don’t synchronize on value types (String, Integer, LocalDateTime)🚨 CriticalValue types are cached internally β†’ accidental cross-object lock sharing
Prefer DateTimeFormatter over SimpleDateFormat🟒 AdvisorySimpleDateFormat is not thread-safe; race conditions likely
Keep lock acquisition order consistent🚨 CriticalInconsistent ordering β†’ deadlocks under load

πŸš€ Concurrent Performance Optimization​

GuidelineImpactWhy It Matters
Use ConcurrentHashMap instead of HashMap + synchronized⚠️ HighFine-grained locking in ConcurrentHashMap β†’ better throughput
Minimize lock scope⚠️ HighSmaller critical sections β†’ higher concurrency, less blocking
Use ThreadLocalRandom instead of Random🟒 AdvisoryAvoids contention on shared Random state
Use LongAdder instead of AtomicLong for hot counters🟒 AdvisoryBetter under high contention due to striped counters

πŸ“Œ Quick Prioritization Table​

AreaMust-Fix 🚨Should-Fix ⚠️Best Practice 🟒
ThreadsParallel I/O streams, ThreadLocal leaks, custom pool for CFuturesThread limits, Future timeoutsThread naming
PoolsUnbounded queues, default @Async, default WebAsyncTask poolsKeep-alive tuningCore=max threads
SafetyLock order consistency, bad value locks, bad DCL patternsStarting threads in constructorsUse DateTimeFormatter
Performanceβ€”ConcurrentHashMap, lock minimizationLongAdder, ThreadLocalRandom

Key Insights​

  • The Critical rules are mostly about preventing outages (e.g., OOM, deadlocks, cascading failures).
  • The High rules aim at avoiding silent performance killers (e.g., starvation, slow I/O).
  • The Advisory rules improve debuggability, maintainability, and long-term scalability.

References