Java Multithreading Cheat Sheet
Covers creating threads, ExecutorService thread pools, synchronization with locks and atomics, and composing async work with CompletableFuture.
2 PagesAdvancedMar 28, 2026
Creating Threads
Two ways to define a task and run it on a new thread.
java
// Extending Threadclass MyThread extends Thread { @Override public void run() { System.out.println("Running in " + getName()); }}new MyThread().start(); // never call run() directly - start() spawns a new thread// Implementing Runnable (preferred - allows extending other classes)Runnable task = () -> System.out.println("Task running");Thread t = new Thread(task);t.start();t.join(); // wait for thread to finish
ExecutorService & Thread Pools
Manage a reusable pool of worker threads instead of raw Thread objects.
java
ExecutorService pool = Executors.newFixedThreadPool(4);Future<Integer> future = pool.submit(() -> { Thread.sleep(100); return 42;});try { Integer result = future.get(); // blocks until the result is ready} catch (InterruptedException | ExecutionException e) { e.printStackTrace();}pool.shutdown(); // stop accepting new tasks, let running ones finish
Synchronization & Locks
Coordinate access to shared mutable state safely.
java
class Counter { private int count = 0; public synchronized void increment() { // intrinsic lock on 'this' count++; }}// Explicit lock for more controlprivate final ReentrantLock lock = new ReentrantLock();public void safeUpdate() { lock.lock(); try { // critical section } finally { lock.unlock(); // always unlock in finally }}// Atomic classes avoid locking entirely for simple countersprivate final AtomicInteger atomicCount = new AtomicInteger(0);atomicCount.incrementAndGet();
Key Concurrency Building Blocks
The core classes and keywords for writing safe concurrent code.
- Thread vs Runnable- Prefer implementing Runnable over extending Thread to keep classes free to extend something else
- synchronized keyword- Applied to methods or blocks to enforce mutual exclusion via an intrinsic monitor lock
- volatile- Guarantees visibility of a variable's latest value across threads, but not atomicity of compound operations
- ExecutorService- Manages a pool of reusable worker threads instead of creating raw Thread objects
- CompletableFuture- Composable async pipeline: supplyAsync().thenApply().thenAccept()
- ConcurrentHashMap- Thread-safe map with fine-grained locking, safe for concurrent reads/writes
- CountDownLatch / CyclicBarrier- Coordination primitives for waiting on multiple threads to reach a point
- Deadlock- Occurs when two or more threads wait on each other's locks forever; avoid by always acquiring locks in a consistent order
CompletableFuture Pipelines
Chain async transformations without blocking, and handle errors inline.
java
CompletableFuture<String> future = CompletableFuture .supplyAsync(() -> fetchUser(1)) // runs on ForkJoinPool.commonPool() by default .thenApply(user -> user.getName()) .thenApply(String::toUpperCase) .exceptionally(ex -> "UNKNOWN"); // fallback on errorfuture.thenAccept(System.out::println); // consume the final resultCompletableFuture<Void> all = CompletableFuture.allOf(future1, future2); // wait for all
Pro Tip
volatile guarantees visibility but not atomicity - a volatile int count; count++; is still a race condition because increment is read-modify-write; use AtomicInteger or synchronized for compound operations on shared state.
Was this cheat sheet helpful?
Explore Topics
#JavaMultithreading#JavaMultithreadingCheatSheet#Programming#Advanced#CreatingThreads#ExecutorServiceThreadPools#SynchronizationLocks#KeyConcurrencyBuildingBlocks#Concurrency#CheatSheet#SkillVeris
Advertisement
Sri Hayavadhana Info-Tech
Professional Web Designing Services
- Responsive Websites
- E-commerce Solutions
- SEO Friendly Design
- Fast & Secure
- Support & Maintenance