<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Arvind Chavan</title>
    <description>The latest articles on DEV Community by Arvind Chavan (@achavan).</description>
    <link>https://dev.to/achavan</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3717418%2Fde712c97-4189-4b2f-86e7-447534c58957.png</url>
      <title>DEV Community: Arvind Chavan</title>
      <link>https://dev.to/achavan</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/achavan"/>
    <language>en</language>
    <item>
      <title>Java Multithreading/Concurrency</title>
      <dc:creator>Arvind Chavan</dc:creator>
      <pubDate>Sun, 18 Jan 2026 06:04:01 +0000</pubDate>
      <link>https://dev.to/achavan/java-multithreadingconcurrency-f4a</link>
      <guid>https://dev.to/achavan/java-multithreadingconcurrency-f4a</guid>
      <description>&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;What is multithreading in Java?&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Multithreading in Java is a feature that allows for the concurrent execution of two or more parts of a program, known as threads, to maximize the utilization of the CPU. Each thread can run in parallel with others, sharing the same memory space.&lt;/p&gt;

&lt;p&gt;Key Concepts&lt;br&gt;
Thread: A thread is a lightweight sub-process, the smallest unit of processing. Multiple threads can exist within a single process.&lt;/p&gt;

&lt;p&gt;Concurrency vs. Parallelism:&lt;/p&gt;

&lt;p&gt;Concurrency: Multiple threads make progress in an interleaved manner on a single CPU core. The system switches between threads, giving the illusion of simultaneous execution.&lt;/p&gt;

&lt;p&gt;Parallelism: Multiple threads run simultaneously on different CPU cores. This is true parallel execution.&lt;/p&gt;

&lt;p&gt;Main Purpose:&lt;br&gt;
Performance: To perform CPU-intensive tasks in parallel, speeding up execution time on multi-core processors.&lt;/p&gt;

&lt;p&gt;Responsiveness: To keep an application responsive. For example, a long-running task (like a network request or file download) can run in a background thread without freezing the user interface.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;How to Create Threads in Java&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;There are two primary ways to create a thread:&lt;/p&gt;

&lt;p&gt;Implementing the Runnable Interface (Preferred Method):&lt;br&gt;
Create a class that implements the java.lang.Runnable interface.&lt;/p&gt;

&lt;p&gt;Implement the run() method, which contains the code to be executed by the thread.&lt;br&gt;
Create an instance of the Thread class, passing your Runnable object to its constructor, and call the start() method.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class MyRunnable implements Runnable {
    public void run() {
        System.out.println("Thread is running by implementing Runnable.");
    }
}

// To start the thread:
MyRunnable myRunnable = new MyRunnable();
Thread thread = new Thread(myRunnable);
thread.start();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class MyThread extends Thread {
    public void run() {
        System.out.println("Thread is running by extending Thread.");
    }
}

// To start the thread:
MyThread thread = new MyThread();
thread.start();

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;What are the different state of thread.&lt;/strong&gt; &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In Java, a thread can be in one of the following states, which are defined in the java.lang.Thread.State enum:&lt;/p&gt;

&lt;p&gt;NEW&lt;br&gt;
A thread that has been created but has not yet started. It remains in this state until the start() method is invoked on it.&lt;/p&gt;

&lt;p&gt;RUNNABLE&lt;br&gt;
A thread that is executing in the Java Virtual Machine (JVM). A thread in this state is either currently running or is ready to run and waiting for its turn to be selected by the thread scheduler.&lt;/p&gt;

&lt;p&gt;BLOCKED&lt;br&gt;
A thread that is waiting to acquire a monitor lock to enter a synchronized block or method. It is blocked because another thread currently holds the lock.&lt;/p&gt;

&lt;p&gt;WAITING&lt;br&gt;
A thread that is waiting indefinitely for another thread to perform a particular action. A thread enters this state by calling one of the following methods:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Object.wait() (with no timeout)
Thread.join() (with no timeout)
LockSupport.park()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;TIMED_WAITING&lt;br&gt;
A thread that is waiting for a specified period of time. A thread enters this state by calling one of these methods with a timeout value:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Thread.sleep(long millis)
Object.wait(long timeout)
Thread.join(long millis)
LockSupport.parkNanos(long nanos)
LockSupport.parkUntil(long deadline)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;TERMINATED&lt;br&gt;
A thread that has completed its execution. This happens when its run() method has finished, either by completing normally or by throwing an unhandled exception&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Explain Synchronization&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Synchronization in Java is a mechanism to control access to shared resources by multiple threads to prevent race conditions and ensure thread safety.&lt;/p&gt;

&lt;p&gt;Key Concepts&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;The Problem It Solves&lt;br&gt;
Race Condition: When multiple threads access and modify shared data simultaneously, leading to unpredictable results&lt;br&gt;
Memory Consistency Errors: When different threads have inconsistent views of the same data&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;How It Works&lt;br&gt;
Every object in Java has an intrinsic lock (monitor). When a thread acquires this lock, other threads must wait until it's released.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Two Main Approaches&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public synchronized void updateData() {
    // Only one thread can execute this at a time
}

public void updateData() {
    synchronized(this) {
        // Only this section is synchronized
    }
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;What is a Deadlock?&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A deadlock is a concurrency failure where two or more threads block forever because each is waiting for a resource (lock) held by another, creating a circular wait.&lt;/p&gt;

&lt;p&gt;Example (Java): two threads acquire the same two locks in opposite order, so neither can proceed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class DeadlockExample {
    private static final Object LOCK_A = new Object();
    private static final Object LOCK_B = new Object();

    public static void main(String[] args) {
        Thread t1 = new Thread(() -&amp;gt; {
            synchronized (LOCK_A) {
                sleep(100);
                synchronized (LOCK_B) {
                    System.out.println("t1 acquired both locks");
                }
            }
        });

        Thread t2 = new Thread(() -&amp;gt; {
            synchronized (LOCK_B) {
                sleep(100);
                synchronized (LOCK_A) {
                    System.out.println("t2 acquired both locks");
                }
            }
        });

        t1.start();
        t2.start();
    }

    private static void sleep(long ms) {
        try { Thread.sleep(ms); } catch (InterruptedException ignored) { }
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;** Lock Use Cases in Java**&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;i.  Method-Level Lock (synchronized method)&lt;br&gt;
   Use Case: When the entire method needs atomic execution (no thread can interrupt).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class DatabaseConnection {
    private static DatabaseConnection instance;

    public static synchronized DatabaseConnection getInstance() {
        if (instance == null) {
            instance = new DatabaseConnection();
        }
        return instance;
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ii.  Class-Level Lock:&lt;br&gt;
Use Case: When all instances of a class share the same resource (static fields).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class OrderIdGenerator {
    private static long currentId = 0;

    public static synchronized long getNextOrderId() {
        return ++currentId;
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;iii.  Object-Level Lock&lt;br&gt;
Use Case: When the entire method needs atomic execution (no thread can interrupt).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class Account {
    private final Object sharedLock;

    public Account(Object lock) {
        this.sharedLock = lock;
    }

    public void transfer(Account target, double amount) {
        synchronized(sharedLock) {  // Both accounts use same lock
            this.balance -= amount;
            target.balance += amount;
        }
    }
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;*&lt;em&gt;Wait, notify and notify all *&lt;/em&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;wait() / notify() / notifyAll() in Java (with example)&lt;/p&gt;

&lt;p&gt;These are Object monitor methods used for thread coordination with synchronized.&lt;/p&gt;

&lt;p&gt;wait() (+ optional timeout): releases the monitor lock and parks the current thread until it’s notified.&lt;/p&gt;

&lt;p&gt;notify(): wakes one arbitrary thread waiting on the same monitor.&lt;/p&gt;

&lt;p&gt;notifyAll(): wakes all threads waiting on the same monitor (they will re-contend for the lock).&lt;/p&gt;

&lt;p&gt;Key rules&lt;br&gt;
Must be called inside a synchronized(lock) block (otherwise IllegalMonitorStateException).&lt;br&gt;
Always use wait() in a while loop (spurious wakeups + condition may no longer hold).&lt;/p&gt;

&lt;p&gt;Prefer notifyAll() when multiple different conditions might be waited on, to avoid “wrong thread woke up” stalls.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class WaitNotifyExample {

    static class BoundedBuffer {
        private final Object lock = new Object();
        private final int capacity;
        private int count = 0;

        BoundedBuffer(int capacity) {
            this.capacity = capacity;
        }

        public void put() throws InterruptedException {
            synchronized (lock) {
                while (count == capacity) {
                    lock.wait(); // releases lock; waits until someone notifies
                }
                count++;
                System.out.println(Thread.currentThread().getName() + " put -&amp;gt; count=" + count);
                lock.notifyAll(); // wake consumers (and possibly producers)
            }
        }

        public void take() throws InterruptedException {
            synchronized (lock) {
                while (count == 0) {
                    lock.wait(); // releases lock; waits until someone notifies
                }
                count--;
                System.out.println(Thread.currentThread().getName() + " took -&amp;gt; count=" + count);
                lock.notifyAll(); // wake producers (and possibly consumers)
            }
        }
    }

    public static void main(String[] args) {
        BoundedBuffer buffer = new BoundedBuffer(2);

        Runnable producer = () -&amp;gt; {
            try {
                for (int i = 0; i &amp;lt; 5; i++) buffer.put();
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        };

        Runnable consumer = () -&amp;gt; {
            try {
                for (int i = 0; i &amp;lt; 5; i++) buffer.take();
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        };

        new Thread(producer, "Producer-1").start();
        new Thread(producer, "Producer-2").start();
        new Thread(consumer, "Consumer-1").start();
        new Thread(consumer, "Consumer-2").start();
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;9) &lt;strong&gt;Atomic classes&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Atomic classes (in java.util.concurrent.atomic) provide lock-free, thread-safe operations on single variables using CAS (compare-and-swap). They give atomicity + visibility without synchronized for many common cases.&lt;/p&gt;

&lt;p&gt;Common atomic types&lt;br&gt;
AtomicInteger, AtomicLong, AtomicBoolean, AtomicReference&lt;br&gt;
AtomicIntegerArray, AtomicLongArray, AtomicReferenceArray&lt;br&gt;
AtomicStampedReference, AtomicMarkableReference (avoid ABA issues)&lt;br&gt;
LongAdder, DoubleAdder, LongAccumulator (best under high contention counters)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Many threads updating a counter: LongAdder&lt;/li&gt;
&lt;li&gt;Need exact atomic increment/sequence: AtomicLong / AtomicInteger&lt;/li&gt;
&lt;li&gt;Atomic swap / init of an object: AtomicReference&lt;/li&gt;
&lt;li&gt;Ensure an action runs once: AtomicBoolean.compareAndSet&lt;/li&gt;
&lt;li&gt;Building lock-free structures / ABA risk: AtomicStampedReference / &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Volatile &lt;/p&gt;

&lt;p&gt;volatile is a field modifier that provides visibility and ordering guarantees between threads, but not mutual exclusion.&lt;/p&gt;

&lt;p&gt;What volatile guarantees&lt;br&gt;
Visibility: when one thread writes a new value to a volatile variable, other threads reading it will see the latest value (no stale cached value).&lt;/p&gt;

&lt;p&gt;Happens-before / ordering: a write to a volatile field happens-before every subsequent read of that same field. This also prevents certain instruction reordering around that read/write.&lt;/p&gt;

&lt;p&gt;What volatile does &lt;em&gt;not&lt;/em&gt; guarantee&lt;br&gt;
Atomicity for compound actions: operations like count++, x = x + 1, or check-then-act are still race-prone even if count/x is volatile.&lt;br&gt;
volatile makes the read/write visible, but ++ is multiple steps (read +\ mutate +\ write).&lt;/p&gt;

&lt;p&gt;Common use cases&lt;br&gt;
Stop/cancel flag&lt;br&gt;
One thread sets a flag, worker threads observe it and stop.&lt;br&gt;
One-way publication of a reference&lt;br&gt;
Publish a fully constructed object to other threads (when the reference is written once and then read many times).&lt;/p&gt;

&lt;p&gt;State signaling&lt;br&gt;
Simple state changes like READY/NOT_READY where only single reads/writes are needed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class VolatileExamples {

    // Use case 1: stop flag (visibility)
    private volatile boolean running = true;

    public void stop() {
        running = false; // other threads will see this
    }

    public void runLoop() {
        while (running) {
            // do work
        }
    }

    // Use case 2: volatile reference publication
    private volatile Config config;

    public void loadConfigOnce() {
        // build locally first (avoid publishing partially-initialized state)
        Config loaded = new Config("v1");
        config = loaded; // safely publish the reference
    }

    public Config getConfig() {
        return config; // sees latest published reference
    }

    // Not safe: volatile does NOT make this atomic
    private volatile int counter = 0;

    public void incrementBroken() {
        counter++; // race: not atomic
    }

    // Correct alternatives:
    // - use AtomicInteger, LongAdder, or synchronized/ReentrantLock
    static final class Config {
        final String version;
        Config(String version) { this.version = version; }
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Lock interface (Java)
Lock is in java.util.concurrent.locks and is an explicit alternative to synchronized. It gives more control: timed/interruptible acquisition, optional fairness, and multiple Conditions (like wait/notify but more flexible).
Key methods&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;lock() - acquire (blocks, not interruptible)&lt;br&gt;
lockInterruptibly() - acquire but can be interrupted while waiting&lt;/p&gt;

&lt;p&gt;tryLock() / tryLock(timeout, unit) - non-blocking / timed&lt;br&gt;
unlock() - release (must be in finally)&lt;/p&gt;

&lt;p&gt;newCondition() - create a Condition for await()/signal() coordination&lt;br&gt;
Common implementations&lt;/p&gt;

&lt;p&gt;ReentrantLock - most common (optionally fair)&lt;/p&gt;

&lt;p&gt;ReentrantReadWriteLock - separate read/write locks (many readers, single writer)&lt;/p&gt;

&lt;p&gt;StampedLock - advanced, includes optimistic reads (not reentrant)&lt;/p&gt;

&lt;p&gt;Minimal example (ReentrantLock)&lt;br&gt;
Uses tryLock and ensures unlock in finally..&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class LockExample {
    private final Lock lock = new ReentrantLock();
    private int counter = 0;

    public void increment() throws InterruptedException {
        if (lock.tryLock(200, TimeUnit.MILLISECONDS)) {
            try {
                counter++; // critical section
            } finally {

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Automatic Classes Vs Volatile&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Volatile :
Guarantees visibility (latest write becomes visible to other threads) and ordering (a write happens-before subsequent reads of the same variable).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Does not make compound operations atomic (e.g., count++, check-then-act).&lt;br&gt;
Best for simple flags or publishing a reference.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class VolatileFlag {
    private volatile boolean running = true;

    public void stop() { running = false; }

    public void runLoop() {
        while (running) {
            // work
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Atomic classes 
Provide atomic read-modify-write operations using CAS (lock-free in many cases).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Also provide visibility guarantees similar to volatile.&lt;/p&gt;

&lt;p&gt;Best for counters, state transitions, and thread-safe updates based on the current value.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import java.util.concurrent.atomic.AtomicInteger;

public class AtomicCounter {
    private final AtomicInteger count = new AtomicInteger();

    public int incAndGet() { return count.incrementAndGet(); }
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;1) What is ScheduledExecutorService?&lt;br&gt;
A Java concurrency API to run tasks after a delay or periodically, using a thread pool.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import java.time.LocalTime;
import java.util.concurrent.*;

public class ScheduledBasics {
    public static void main(String[] args) throws Exception {
        ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(2);

        scheduler.schedule(() -&amp;gt;
                System.out.println(LocalTime.now() + " \- runs once after 1s"),
            1, TimeUnit.SECONDS);

        scheduler.shutdown();
        scheduler.awaitTermination(5, TimeUnit.SECONDS);
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ScheduledExecutorService - common questions, answers, and examples&lt;br&gt;
1) What is ScheduledExecutorService?&lt;br&gt;
A Java concurrency API to run tasks after a delay or periodically, using a thread pool.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import java.time.LocalTime;
import java.util.concurrent.*;

public class ScheduledBasics {
    public static void main(String[] args) throws Exception {
        ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(2);

        scheduler.schedule(() -&amp;gt;
                System.out.println(LocalTime.now() + " \- runs once after 1s"),
            1, TimeUnit.SECONDS);

        scheduler.shutdown();
        scheduler.awaitTermination(5, TimeUnit.SECONDS);
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;2) How is it different from Timer?&lt;/p&gt;

&lt;p&gt;ScheduledExecutorService is preferred because it:&lt;br&gt;
supports multiple threads&lt;br&gt;
handles exceptions better (a Timer can die if a task throws)&lt;br&gt;
integrates cleanly with Future, cancellation, shutdown, etc.&lt;/p&gt;



&lt;p&gt;3) How to run a task once after a delay?&lt;br&gt;
Use schedule(...).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import java.util.concurrent.*;

public class ScheduleOnce {
    public static void main(String[] args) throws Exception {
        ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();

        ScheduledFuture&amp;lt;String&amp;gt; f = scheduler.schedule(() -&amp;gt; "done", 2, TimeUnit.SECONDS);
        System.out.println("Result: " + f.get());

        scheduler.shutdown();
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;4) How to run repeatedly at a fixed rate?&lt;/p&gt;

&lt;p&gt;Use scheduleAtFixedRate(...). It tries to keep the rate (can “catch up” if a run is delayed).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import java.time.LocalTime;
import java.util.concurrent.*;

public class FixedRateExample {
    public static void main(String[] args) throws Exception {
        ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);

        ScheduledFuture&amp;lt;?&amp;gt; handle = scheduler.scheduleAtFixedRate(() -&amp;gt; {
            System.out.println(LocalTime.now() + " \- tick");
            sleep(700);
        }, 0, 1, TimeUnit.SECONDS);

        scheduler.schedule(() -&amp;gt; handle.cancel(false), 5, TimeUnit.SECONDS);
        scheduler.schedule(scheduler::shutdown, 6, TimeUnit.SECONDS);

        scheduler.awaitTermination(10, TimeUnit.SECONDS);
    }

    private static void sleep(long ms) {
        try { Thread.sleep(ms); } catch (InterruptedException e) { Thread.currentThread().interrupt(); }
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;5) How to run repeatedly with fixed delay?&lt;/p&gt;

&lt;p&gt;Use scheduleWithFixedDelay(...). Next run starts after the previous finishes plus delay.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import java.time.LocalTime;
import java.util.concurrent.*;

public class FixedDelayExample {
    public static void main(String[] args) throws Exception {
        ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);

        ScheduledFuture&amp;lt;?&amp;gt; handle = scheduler.scheduleWithFixedDelay(() -&amp;gt; {
            System.out.println(LocalTime.now() + " \- start");
            sleep(1200);
            System.out.println(LocalTime.now() + " \- end");
        }, 0, 1, TimeUnit.SECONDS);

        scheduler.schedule(() -&amp;gt; handle.cancel(false), 6, TimeUnit.SECONDS);
        scheduler.schedule(scheduler::shutdown, 7, TimeUnit.SECONDS);

        scheduler.awaitTermination(10, TimeUnit.SECONDS);
    }

    private static void sleep(long ms) {
        try { Thread.sleep(ms); } catch (InterruptedException e) { Thread.currentThread().interrupt(); }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;6) Which one should I use: fixed rate vs fixed delay?&lt;br&gt;
Use scheduleAtFixedRate for regular ticks (metrics, polling on wall clock).&lt;/p&gt;

&lt;p&gt;Use scheduleWithFixedDelay when work time varies and you must avoid overlap/catch-up.&lt;/p&gt;



&lt;p&gt;7) Does &lt;/p&gt;

&lt;p&gt;ScheduledExecutorService run tasks in parallel?&lt;br&gt;
Yes, if the pool has multiple threads. With a single thread, tasks run sequentially.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import java.util.concurrent.*;

public class ParallelScheduling {
    public static void main(String[] args) throws Exception {
        ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(2);

        scheduler.schedule(() -&amp;gt; work("A"), 0, TimeUnit.SECONDS);
        scheduler.schedule(() -&amp;gt; work("B"), 0, TimeUnit.SECONDS);

        scheduler.shutdown();
        scheduler.awaitTermination(5, TimeUnit.SECONDS);
    }

    private static void work(String name) {
        System.out.println("Start " + name + " on " + Thread.currentThread().getName());
        try { Thread.sleep(1000); } catch (InterruptedException e) { Thread.currentThread().interrupt(); }
        System.out.println("End " + name);
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;8) What happens if a scheduled task throws an exception?&lt;br&gt;
For periodic tasks, an uncaught exception typically stops future executions of that task. Catch exceptions inside the runnable.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import java.util.concurrent.*;
public class ExceptionSafeTask {
    public static void main(String[] args) throws Exception {
        ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();

        scheduler.scheduleAtFixedRate(() -&amp;gt; {
            try {
                System.out.println("Running...");
                if (Math.random() &amp;lt; 0.5) throw new RuntimeException("boom");
            } catch (Exception e) {
                System.out.println("Handled: " + e.getMessage());
            }
        }, 0, 1, TimeUnit.SECONDS);

        Thread.sleep(4000);
        scheduler.shutdownNow();
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;9) How do I cancel a scheduled task?&lt;br&gt;
Use the returned ScheduledFuture and call cancel(...).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import java.util.concurrent.*;

public class CancelExample {
    public static void main(String[] args) throws Exception {
        ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();

        ScheduledFuture&amp;lt;?&amp;gt; handle = scheduler.scheduleAtFixedRate(
            () -&amp;gt; System.out.println("tick"),
            0, 500, TimeUnit.MILLISECONDS
        );

        Thread.sleep(1600);
        handle.cancel(false); // `false` \= don’t interrupt if currently running

        scheduler.shutdown();
        scheduler.awaitTermination(2, TimeUnit.SECONDS);
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;10) What is the meaning of cancel(true) vs cancel(false)?&lt;br&gt;
true: attempts to interrupt the running thread.&lt;/p&gt;

&lt;p&gt;false: lets current run finish, prevents future runs.&lt;/p&gt;



&lt;p&gt;11) How do I shut down properly?&lt;br&gt;
Use shutdown() for graceful stop, then awaitTermination(...). Use shutdownNow() for forced interruption.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import java.util.concurrent.*;

public class ShutdownExample {
    public static void main(String[] args) throws Exception {
        ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);

        scheduler.scheduleAtFixedRate(() -&amp;gt; System.out.println("tick"), 0, 1, TimeUnit.SECONDS);

        Thread.sleep(2500);
        scheduler.shutdown(); // graceful
        if (!scheduler.awaitTermination(2, TimeUnit.SECONDS)) {
            scheduler.shutdownNow(); // forced
        }
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;12) How to schedule based on a specific time of day?&lt;br&gt;
Compute the initial delay, then run daily.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import java.time.*;
import java.util.concurrent.*;

public class DailyAtTime {
    public static void main(String[] args) {
        ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();

        LocalTime target = LocalTime.of(2, 0); // 02:00
        long initialDelayMs = computeInitialDelayMs(target);
        long dayMs = TimeUnit.DAYS.toMillis(1);

        scheduler.scheduleAtFixedRate(
            () -&amp;gt; System.out.println("Daily job at " + LocalDateTime.now()),
            initialDelayMs, dayMs, TimeUnit.MILLISECONDS
        );
    }

    private static long computeInitialDelayMs(LocalTime target) {
        ZonedDateTime now = ZonedDateTime.now();
        ZonedDateTime next = now.with(target);
        if (!next.isAfter(now)) next = next.plusDays(1);
        return Duration.between(now, next).toMillis();
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;13) Can it return a value?&lt;br&gt;
Yes. schedule(Callable, ...) returns ScheduledFuture.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import java.util.concurrent.*;

public class CallableExample {
    public static void main(String[] args) throws Exception {
        ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();

        ScheduledFuture&amp;lt;Integer&amp;gt; f = scheduler.schedule(() -&amp;gt; 40 + 2, 1, TimeUnit.SECONDS);
        System.out.println("Value: " + f.get());

        scheduler.shutdown();
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;14) How to handle timeouts when waiting for results?&lt;br&gt;
Use get(timeout, unit).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import java.util.concurrent.*;

public class TimeoutGet {
    public static void main(String[] args) throws Exception {
        ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();

        ScheduledFuture&amp;lt;String&amp;gt; f = scheduler.schedule(() -&amp;gt; {
            Thread.sleep(2000);
            return "ok";
        }, 0, TimeUnit.SECONDS);

        try {
            System.out.println(f.get(1, TimeUnit.SECONDS));
        } catch (TimeoutException e) {
            System.out.println("Timed out");
            f.cancel(true);
        } finally {
            scheduler.shutdownNow();
        }
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;15) How to avoid overlapping executions for periodic tasks?&lt;/p&gt;

&lt;p&gt;If overlap is a risk, prefer:&lt;br&gt;
scheduleWithFixedDelay (naturally non-overlapping in one thread), or&lt;br&gt;
a pool size of 1, or&lt;br&gt;
a lock/guard inside the task.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicBoolean;

public class NoOverlapGuard {
    private static final AtomicBoolean running = new AtomicBoolean(false);

    public static void main(String[] args) {
        ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(2);

        scheduler.scheduleAtFixedRate(() -&amp;gt; {
            if (!running.compareAndSet(false, true)) return;
            try {
                Thread.sleep(1200);
                System.out.println("Work done by " + Thread.currentThread().getName());
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            } finally {
                running.set(false);
            }
        }, 0, 500, TimeUnit.MILLISECONDS);
    }
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;*&lt;em&gt;newCachedThreadPool vs newFixedThreadPool (ExecutorService)&lt;br&gt;
*&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Cached (Executors.newCachedThreadPool())&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;What it is&lt;br&gt;
Thread pool with 0 core threads and unbounded max threads.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Uses a SynchronousQueue (tasks are handed directly to a thread; if none is free, a new thread is created).&lt;/p&gt;

&lt;p&gt;Idle threads are reused and typically removed after ~60s.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Behavior
Can grow very large under load =&amp;gt; risk of CPU thrash / memory pressure.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Low latency for bursts (no waiting queue).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use cases
Short-lived, bursty, non-blocking tasks, where throughput matters and load is controlled.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example: handling many small asynchronous callbacks, lightweight background jobs that finish quickly.&lt;/p&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Fixed (Executors.newFixedThreadPool(n))&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;What it is&lt;br&gt;
Thread pool with exactly n threads (bounded concurrency).&lt;br&gt;
Uses an (effectively) unbounded queue (LinkedBlockingQueue) by default.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Behavior&lt;br&gt;
Concurrency is limited to n =&amp;gt; stable CPU/memory usage.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If tasks arrive faster than they complete, they queue up =&amp;gt; risk of high queue growth / latency.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use cases
Steady workloads where you must cap parallelism.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;CPU-bound work: set n around number of cores.&lt;/p&gt;

&lt;p&gt;I/O-bound work: n can be higher, but still bounded to protect downstream services.&lt;/p&gt;



&lt;p&gt;Quick rule of thumb&lt;/p&gt;

&lt;p&gt;Use fixed when you need predictable resource usage and backpressure via queuing.&lt;/p&gt;

&lt;p&gt;Use cached only when tasks are very short, non-blocking, and request rate is controlled (or you can tolerate thread growth).&lt;/p&gt;



&lt;p&gt;Minimal examples&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cached pool for bursty short tasks
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class CachedPoolDemo {
    public static void main(String[] args) {
        ExecutorService es = Executors.newCachedThreadPool();

        for (int i = 0; i &amp;lt; 1000; i++) {
            int id = i;
            es.submit(() -&amp;gt; {
                // short task
                return id;
            });
        }

        es.shutdown();
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Fixed pool to cap concurrency (e.g., calling an external API)
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class FixedPoolDemo {
    public static void main(String[] args) {
        int maxParallelCalls = 10;
        ExecutorService es = Executors.newFixedThreadPool(maxParallelCalls);

        for (int i = 0; i &amp;lt; 1000; i++) {
            es.submit(() -&amp;gt; {
                // I/O call \- limited to 10 concurrent executions
                // callExternalService();
            });
        }

        es.shutdown();
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;ExecutorService: execute() vs submit()&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;execute(Runnable)
Return type: void (= no handle to track completion)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Use when: fire-and-forget tasks where you do not need a result or cancellation handle.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Exception handling&lt;br&gt;
: if the task throws, it goes to the thread’s UncaughtExceptionHandler (often just logged). You cannot observe it via a Future.&lt;br&gt;
submit(...)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Overloads&lt;br&gt;
: submit(Runnable), submit(Callable), submit(Runnable, V result)&lt;br&gt;
Return type: Future&amp;lt;?&amp;gt; / Future (= enables get(), cancel(), status checks)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use when&lt;br&gt;
: you need a result, need to wait, need to cancel, or need to capture exceptions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Exception handling&lt;br&gt;
: exceptions are captured and rethrown as ExecutionException from future.get().&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import java.util.concurrent.*;

public class ExecuteVsSubmitDemo {
    public static void main(String[] args) throws Exception {
        ExecutorService es = Executors.newFixedThreadPool(1);

        // 1) execute(): no Future, exception is not observable via caller
        es.execute(() -&amp;gt; {
            System.out.println("execute running");
            throw new RuntimeException("boom from execute");
        });

        // 2) submit(Runnable): returns Future, exception surfaces on get()
        Future&amp;lt;?&amp;gt; f1 = es.submit(() -&amp;gt; {
            System.out.println("submit(Runnable) running");
            throw new RuntimeException("boom from submit runnable");
        });

        try {
            f1.get(); // throws ExecutionException wrapping the original exception
        } catch (ExecutionException e) {
            System.out.println("Caught from submit(Runnable): " + e.getCause());
        }

        // 3) submit(Callable): returns a value
        Future&amp;lt;Integer&amp;gt; f2 = es.submit(() -&amp;gt; 40 + 2);
        System.out.println("Callable result: " + f2.get());

        es.shutdown();
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Practical rule&lt;/p&gt;

&lt;p&gt;Use execute() when you truly do not care about completion/result.&lt;/p&gt;

&lt;p&gt;Use submit() when you need Future capabilities or want exceptions to be observable to the caller.&lt;/p&gt;

&lt;p&gt;How do you gracefully shut down an ExecutorService?&lt;/p&gt;

&lt;p&gt;You can gracefully shut down an ExecutorService by calling the shutdown() method. &lt;br&gt;
This initiates an orderly shutdown in which previously submitted tasks are executed, but no new tasks will be accepted. &lt;br&gt;
You can also use shutdownNow() to attempt to stop all actively executing tasks and halt the processing of waiting tasks.&lt;/p&gt;

&lt;p&gt;Difference between shutdown() and shutdownNow() methods in ExecutorService?&lt;/p&gt;

&lt;p&gt;shutdown(): Initiates an orderly shutdown, where tasks that were already submitted are completed before the service is fully shut down. No new tasks will be accepted.&lt;/p&gt;

&lt;p&gt;shutdownNow(): Tries to stop all actively executing tasks and attempts to stop any waiting tasks. It returns a list of the tasks that were waiting to be executed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Internal Working of ThreadPoolExecutor&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Key internal parts&lt;br&gt;
Worker threads set: a collection of Worker objects (each wraps a Thread and runs a task loop).&lt;/p&gt;

&lt;p&gt;Work queue: a BlockingQueue that holds submitted tasks waiting for a thread.&lt;/p&gt;

&lt;p&gt;Pool sizing rules:&lt;br&gt;
corePoolSize: baseline number of threads kept (even if idle, unless allowCoreThreadTimeOut(true)).&lt;/p&gt;

&lt;p&gt;maximumPoolSize: hard cap on threads.&lt;/p&gt;

&lt;p&gt;keepAliveTime: how long non-core (and optionally core) idle threads live.&lt;br&gt;
Control state: a single atomic ctl combines:&lt;br&gt;
run state (RUNNING, SHUTDOWN, STOP, TIDYING, TERMINATED)&lt;br&gt;
worker count (how many threads currently exist)&lt;/p&gt;

&lt;p&gt;Rejection policy: what happens when it cannot accept more work (AbortPolicy, CallerRunsPolicy, etc.).&lt;/p&gt;

&lt;p&gt;2) What happens on execute(Runnable)&lt;br&gt;
Internally the logic is roughly:&lt;br&gt;
If current workers &amp;lt; corePoolSize&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;create a new worker thread immediately to run the task (bypasses the queue).
Else try to enqueue the task (workQueue.offer(task))&lt;/li&gt;
&lt;li&gt;if enqueue succeeds, the task waits until a worker takes it.&lt;/li&gt;
&lt;li&gt;it then rechecks state: if pool is shutting down and can’t run it, it removes and rejects.
If enqueue fails (queue full or a SynchronousQueue handoff failed)&lt;/li&gt;
&lt;li&gt;if workers &amp;lt; maximumPoolSize, create a new non-core worker thread to run it.
Else reject&lt;/li&gt;
&lt;li&gt;apply the configured RejectedExecutionHandler.
This is why queue choice matters:
LinkedBlockingQueue (often unbounded): usually queues instead of growing threads, so max threads may never be reached.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;SynchronousQueue: never stores tasks, so it tends to create threads up to max under load.&lt;br&gt;
3) Worker thread main loop (how tasks actually run)&lt;br&gt;
Each worker does:&lt;br&gt;
run an initial task (if any),&lt;br&gt;
then repeatedly:&lt;br&gt;
fetch next task via getTask():&lt;br&gt;
blocks on queue.take() if core threads are kept alive,&lt;br&gt;
or uses timed poll(keepAliveTime) for threads that may time out,&lt;br&gt;
run task inside a try/finally,&lt;br&gt;
update completed-task counts,&lt;br&gt;
if the pool is stopping/shutdown and queue empty, exit.&lt;br&gt;
If a task throws an unchecked exception and it isn’t caught inside the task, that worker thread typically dies, and the executor may create a replacement (depending on state and sizing).&lt;br&gt;
4) Shutdown states&lt;br&gt;
shutdown():&lt;br&gt;
stops accepting new tasks,&lt;br&gt;
continues executing queued tasks,&lt;br&gt;
interrupts only idle workers to help them exit when done.&lt;br&gt;
shutdownNow():&lt;br&gt;
attempts to stop immediately,&lt;br&gt;
interrupts workers (even running),&lt;br&gt;
drains queue and returns pending tasks.&lt;br&gt;
5) Minimal example (shows sizing + rejection)&lt;br&gt;
Briefly: this config creates up to 2 core threads, queues up to 2 tasks, then grows to max 4 threads; after that it rejects.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import java.util.concurrent.*;

public class ThreadPoolExecutorInternalsDemo {
    public static void main(String[] args) throws InterruptedException {
        ThreadPoolExecutor ex = new ThreadPoolExecutor(
                2,                      // corePoolSize
                4,                      // maximumPoolSize
                10, TimeUnit.SECONDS,   // keepAliveTime
                new ArrayBlockingQueue&amp;lt;&amp;gt;(2), // bounded queue (capacity 2)
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy() // reject when saturated
        );

        for (int i = 1; i &amp;lt;= 8; i++) {
            int id = i;
            try {
                ex.execute(() -&amp;gt; {
                    System.out.println("Task " + id + " on " + Thread.currentThread().getName());
                    sleep(1000);
                });
            } catch (RejectedExecutionException e) {
                System.out.println("Rejected task " + id);
            }
        }

        ex.shutdown();
        ex.awaitTermination(30, TimeUnit.SECONDS);
        System.out.println("Largest pool size: " + ex.getLargestPoolSize());
        System.out.println("Completed tasks: " + ex.getCompletedTaskCount());
    }

    private static void sleep(long ms) {
        try {
            Thread.sleep(ms);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this run you’ll typically observe: first 2 tasks start (core threads), next 2 queue, next 2 start new threads (up to max 4), remaining tasks get rejected once both queue and max threads are saturated.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Exception handling in threading (Java)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;1) Exceptions in a Thread&lt;br&gt;
An exception thrown from run() does not propagate to the caller thread. Handle it inside run() or use an UncaughtExceptionHandler.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class ThreadExceptionHandling {
    public static void main(String[] args) {
        Thread t = new Thread(() -&amp;gt; {
            throw new RuntimeException("boom");
        });

        t.setUncaughtExceptionHandler((thread, ex) -&amp;gt; {
            System.err.println("Uncaught in " + thread.getName() + ": " + ex.getMessage());
        });

        t.start();
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;2) Exceptions in ExecutorService: execute() vs submit()&lt;br&gt;
execute() = exception goes to the worker thread’s UncaughtExceptionHandler (often just logged).&lt;br&gt;
submit() = exception is stored in the Future; you see it only when calling get().&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import java.util.concurrent.*;

public class ExecutorExceptionHandling {
    public static void main(String[] args) throws Exception {
        ExecutorService es = Executors.newFixedThreadPool(1);

        es.execute(() -&amp;gt; { throw new RuntimeException("boom from execute"); });

        Future&amp;lt;?&amp;gt; f = es.submit(() -&amp;gt; { throw new RuntimeException("boom from submit"); });
        try {
            f.get();
        } catch (ExecutionException e) {
            System.err.println("Caught via Future.get(): " + e.getCause());
        } finally {
            es.shutdown();
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;3) Exceptions in ScheduledExecutorService periodic tasks&lt;br&gt;
For scheduleAtFixedRate / scheduleWithFixedDelay: an uncaught exception typically stops future executions of that periodic task. Catch inside the runnable to keep it running.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import java.util.concurrent.*;

public class ScheduledExceptionHandling {
    public static void main(String[] args) throws InterruptedException {
        ScheduledExecutorService ses = Executors.newSingleThreadScheduledExecutor();

        ses.scheduleAtFixedRate(() -&amp;gt; {
            try {
                System.out.println("tick");
                if (System.nanoTime() % 2 == 0) throw new RuntimeException("intermittent");
            } catch (Exception e) {
                System.err.println("Handled inside task: " + e.getMessage());
            }
        }, 0, 500, TimeUnit.MILLISECONDS);

        Thread.sleep(3000);
        ses.shutdownNow();
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;4) Recommended pattern&lt;br&gt;
Catch exceptions inside tasks for resilience.&lt;br&gt;
For executors, prefer submit() when you must observe failures (&lt;code&gt;Future&lt;/code&gt; + &lt;code&gt;get()&lt;/code&gt;).&lt;br&gt;
Set a default handler for unexpected failures:&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;BlockingQueue types commonly used with ThreadPoolExecutor&lt;br&gt;
*&lt;/em&gt;&lt;br&gt;
In ThreadPoolExecutor, the BlockingQueue choice determines whether the pool queues, hands off, or forces thread growth, and how backpressure happens.&lt;/p&gt;

&lt;p&gt;LinkedBlockingQueue&lt;br&gt;
Type: linked, optionally bounded (constructor can take capacity); often used unbounded.&lt;br&gt;
Behavior: tasks mostly queue once corePoolSize threads are busy; pool typically does not grow beyond core if queue is unbounded.&lt;br&gt;
When to use: stable throughput, avoid thread explosion; prefer a bounded capacity in production.&lt;/p&gt;

&lt;p&gt;ArrayBlockingQueue&lt;br&gt;
Type: bounded array-backed FIFO.&lt;br&gt;
Behavior: once full, executor will try to create threads up to maximumPoolSize; then reject.&lt;br&gt;
When to use: strong backpressure + predictable memory; common “safe default” with a rejection policy.&lt;/p&gt;

&lt;p&gt;SynchronousQueue&lt;br&gt;
Type: zero-capacity handoff queue (no storage).&lt;br&gt;
Behavior: each submit must be immediately handed to a worker; if none idle, executor tends to create new threads up to maximumPoolSize; then reject.&lt;br&gt;
When to use: very short tasks, low queuing latency; used by newCachedThreadPool().&lt;/p&gt;

&lt;p&gt;PriorityBlockingQueue&lt;br&gt;
Type: unbounded priority queue (tasks must be Comparable or use a wrapper with a comparator).&lt;br&gt;
Behavior: tasks ordered by priority, not FIFO; generally unbounded =&amp;gt; risk of memory growth.&lt;br&gt;
When to use: when task ordering by priority matters.&lt;/p&gt;

&lt;p&gt;DelayQueue&lt;br&gt;
Type: unbounded, time-based ordering (elements implement Delayed).&lt;br&gt;
Behavior: tasks become available only after delay; not typically used directly with ThreadPoolExecutor (more common with ScheduledThreadPoolExecutor).&lt;br&gt;
When to use: delayed execution patterns.&lt;/p&gt;

&lt;p&gt;LinkedTransferQueue&lt;br&gt;
Type: unbounded transfer queue (can behave like handoff when consumers waiting).&lt;br&gt;
Behavior: can reduce latency under contention; still unbounded by default.&lt;br&gt;
When to use: high-throughput handoff/queue hybrid cases (advanced tuning).&lt;br&gt;
Notes&lt;br&gt;
With unbounded queues (LinkedBlockingQueue default, PriorityBlockingQueue, etc.), maximumPoolSize is often effectively ignored because tasks queue instead of triggering new threads.&lt;/p&gt;

&lt;p&gt;Prefer bounded queues (ArrayBlockingQueue or bounded LinkedBlockingQueue) + an explicit RejectedExecutionHandler for predictable backpressure.&lt;/p&gt;

&lt;p&gt;Java concurrency classes (common) + use cases + minimal examples&lt;br&gt;
1) Executors &amp;amp; thread pools&lt;br&gt;
Executor / ExecutorService - run tasks asynchronously, manage a pool, shutdown lifecycle&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import java.util.concurrent.*;

class ExExecutorService {
  public static void main(String[] args) throws Exception {
    ExecutorService es = Executors.newFixedThreadPool(2);

    Future&amp;lt;Integer&amp;gt; f = es.submit(() -&amp;gt; 40 + 2);
    System.out.println(f.get());

    es.shutdown();
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ThreadPoolExecutor - fully tunable pool (core/max, queue, rejection)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import java.util.concurrent.*;

class ExThreadPoolExecutor {
  public static void main(String[] args) {
    ThreadPoolExecutor ex = new ThreadPoolExecutor(
        2, 4, 10, TimeUnit.SECONDS,
        new ArrayBlockingQueue&amp;lt;&amp;gt;(100),
        new ThreadPoolExecutor.CallerRunsPolicy()
    );

    ex.execute(() -&amp;gt; System.out.println(Thread.currentThread().getName()));
    ex.shutdown();
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ScheduledExecutorService / ScheduledThreadPoolExecutor - delayed/periodic tasks&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import java.util.concurrent.*;

class ExScheduled {
  public static void main(String[] args) throws Exception {
    ScheduledExecutorService ses = Executors.newSingleThreadScheduledExecutor();

    ses.schedule(() -&amp;gt; System.out.println("delayed"), 200, TimeUnit.MILLISECONDS);

    Thread.sleep(400);
    ses.shutdown();
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ForkJoinPool - CPU bound divide&amp;amp;conquer, work stealing&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import java.util.concurrent.*;

class ExForkJoin {
  static class SumTask extends RecursiveTask&amp;lt;Long&amp;gt; {
    private final long n;
    SumTask(long n) { this.n = n; }
    @Override protected Long compute() {
      if (n &amp;lt;= 10_000) {
        long s = 0;
        for (long i = 1; i &amp;lt;= n; i++) s += i;
        return s;
      }
      long mid = n / 2;
      SumTask left = new SumTask(mid);
      SumTask right = new SumTask(n - mid);
      left.fork();
      return right.compute() + left.join();
    }
  }

  public static void main(String[] args) {
    ForkJoinPool p = ForkJoinPool.commonPool();
    System.out.println(p.invoke(new SumTask(1_000_000)));
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;2) Futures &amp;amp; async composition&lt;br&gt;
Callable - task that returns a value and can throw checked exceptions&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import java.util.concurrent.*;

class ExCallable {
  public static void main(String[] args) throws Exception {
    Callable&amp;lt;String&amp;gt; c = () -&amp;gt; "ok";
    System.out.println(c.call());
  }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Future - represents pending result (get/cancel/isDone)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import java.util.concurrent.*;

class ExFuture {
  public static void main(String[] args) throws Exception {
    ExecutorService es = Executors.newSingleThreadExecutor();
    Future&amp;lt;String&amp;gt; f = es.submit(() -&amp;gt; "result");
    System.out.println(f.get());
    es.shutdown();
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;FutureTask - Runnable + Future combo (manual start, caching)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import java.util.concurrent.*;

class ExFutureTask {
  public static void main(String[] args) throws Exception {
    FutureTask&amp;lt;Integer&amp;gt; ft = new FutureTask&amp;lt;&amp;gt;(() -&amp;gt; 1 + 2);
    new Thread(ft).start();
    System.out.println(ft.get());
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;CompletableFuture / CompletionStage - async pipelines, combine stages&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import java.util.concurrent.*;

class ExCompletableFuture {
  public static void main(String[] args) throws Exception {
    CompletableFuture&amp;lt;Integer&amp;gt; cf =
        CompletableFuture.supplyAsync(() -&amp;gt; 21)
            .thenApply(x -&amp;gt; x * 2);

    System.out.println(cf.get());
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ExecutorCompletionService - submit many tasks, consume results as they finish&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import java.util.concurrent.*;

class ExCompletionService {
  public static void main(String[] args) throws Exception {
    ExecutorService es = Executors.newFixedThreadPool(3);
    CompletionService&amp;lt;Integer&amp;gt; cs = new ExecutorCompletionService&amp;lt;&amp;gt;(es);

    for (int i = 0; i &amp;lt; 5; i++) {
      int id = i;
      cs.submit(() -&amp;gt; id * id);
    }

    for (int i = 0; i &amp;lt; 5; i++) {
      System.out.println(cs.take().get());
    }

    es.shutdown();
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;3) Coordination primitives (synchronizers)&lt;br&gt;
CountDownLatch - wait for N events (one shot)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import java.util.concurrent.*;

class ExCountDownLatch {
  public static void main(String[] args) throws Exception {
    CountDownLatch latch = new CountDownLatch(2);

    new Thread(() -&amp;gt; { work(); latch.countDown(); }).start();
    new Thread(() -&amp;gt; { work(); latch.countDown(); }).start();

    latch.await();
    System.out.println("done");
  }

  static void work() { /* do work */ }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;CyclicBarrier - all parties meet each phase (reusable)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import java.util.concurrent.*;

class ExCyclicBarrier {
  public static void main(String[] args) {
    CyclicBarrier barrier = new CyclicBarrier(3, () -&amp;gt; System.out.println("phase complete"));

    Runnable r = () -&amp;gt; {
      try {
        barrier.await();
      } catch (Exception ignored) {}
    };

    new Thread(r).start();
    new Thread(r).start();
    new Thread(r).start();
  }
}
Phaser - flexible barrier with dynamic registration
import java.util.concurrent.*;

class ExPhaser {
  public static void main(String[] args) {
    Phaser phaser = new Phaser(1);

    phaser.register();
    new Thread(() -&amp;gt; { phaser.arriveAndAwaitAdvance(); }).start();

    phaser.arriveAndAwaitAdvance();
    System.out.println("advanced");
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Semaphore - limit concurrent access (permits)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import java.util.concurrent.*;

class ExSemaphore {
  public static void main(String[] args) throws Exception {
    Semaphore sem = new Semaphore(2);

    Runnable r = () -&amp;gt; {
      try {
        sem.acquire();
        try { Thread.sleep(100); } catch (InterruptedException ignored) {}
      } catch (InterruptedException ignored) {
      } finally {
        sem.release();
      }
    };

    for (int i = 0; i &amp;lt; 5; i++) new Thread(r).start();
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Exchanger - 2 threads swap data at rendezvous&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import java.util.concurrent.*;

class ExExchanger {
  public static void main(String[] args) {
    Exchanger&amp;lt;String&amp;gt; ex = new Exchanger&amp;lt;&amp;gt;();

    new Thread(() -&amp;gt; {
      try { System.out.println("A got " + ex.exchange("fromA")); } catch (InterruptedException ignored) {}
    }).start();

    new Thread(() -&amp;gt; {
      try { System.out.println("B got " + ex.exchange("fromB")); } catch (InterruptedException ignored) {}
    }).start();
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;LockSupport - low level park/unpark building block&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import java.util.concurrent.locks.LockSupport;

class ExLockSupport {
  public static void main(String[] args) throws Exception {
    Thread t = new Thread(() -&amp;gt; {
      LockSupport.park();
      System.out.println("unparked");
    });
    t.start();

    Thread.sleep(100);
    LockSupport.unpark(t);
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;4) Locks &amp;amp; conditions&lt;br&gt;
Lock / ReentrantLock - explicit mutual exclusion, tryLock, fairness&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import java.util.concurrent.locks.*;

class ExReentrantLock {
  private static final Lock lock = new ReentrantLock();

  public static void main(String[] args) {
    lock.lock();
    try {
      System.out.println("critical section");
    } finally {
      lock.unlock();
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Condition - multiple wait sets per lock&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import java.util.concurrent.locks.*;

class ExCondition {
  static final ReentrantLock lock = new ReentrantLock();
  static final Condition ready = lock.newCondition();
  static boolean done = false;

  public static void main(String[] args) throws Exception {
    Thread waiter = new Thread(() -&amp;gt; {
      lock.lock();
      try {
        while (!done) ready.await();
        System.out.println("released");
      } catch (InterruptedException ignored) {
      } finally {
        lock.unlock();
      }
    });
    waiter.start();

    Thread.sleep(100);
    lock.lock();
    try {
      done = true;
      ready.signalAll();
    } finally {
      lock.unlock();
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ReadWriteLock / ReentrantReadWriteLock - many readers, few writers&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import java.util.concurrent.locks.*;

class ExReadWriteLock {
  static final ReentrantReadWriteLock rw = new ReentrantReadWriteLock();
  static int value = 0;

  static int read() {
    rw.readLock().lock();
    try { return value; }
    finally { rw.readLock().unlock(); }
  }

  static void write(int v) {
    rw.writeLock().lock();
    try { value = v; }
    finally { rw.writeLock().unlock(); }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;StampedLock - optimistic reads for high read concurrency (advanced)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
import java.util.concurrent.locks.StampedLock;

class ExStampedLock {
  static final StampedLock sl = new StampedLock();
  static int x = 0;

  static int optimisticRead() {
    long stamp = sl.tryOptimisticRead();
    int v = x;
    if (!sl.validate(stamp)) {
      stamp = sl.readLock();
      try { v = x; }
      finally { sl.unlockRead(stamp); }
    }
    return v;
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;5) Atomics &amp;amp; contention reducers&lt;br&gt;
AtomicInteger / AtomicLong / AtomicReference - CAS based updates&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import java.util.concurrent.atomic.*;

class ExAtomics {
  public static void main(String[] args) {
    AtomicInteger ai = new AtomicInteger(0);
    ai.incrementAndGet();
    System.out.println(ai.get());

    AtomicReference&amp;lt;String&amp;gt; ar = new AtomicReference&amp;lt;&amp;gt;("a");
    ar.compareAndSet("a", "b");
    System.out.println(ar.get());
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;AtomicIntegerArray / AtomicLongArray - atomic ops on array elements&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import java.util.concurrent.atomic.*;

class ExAtomicArray {
  public static void main(String[] args) {
    AtomicIntegerArray a = new AtomicIntegerArray(3);
    a.incrementAndGet(1);
    System.out.println(a.get(1));
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;AtomicStampedReference / AtomicMarkableReference - mitigate ABA patterns&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import java.util.concurrent.atomic.*;

class ExStampedRef {
  public static void main(String[] args) {
    AtomicStampedReference&amp;lt;String&amp;gt; ref = new AtomicStampedReference&amp;lt;&amp;gt;("v1", 0);
    int[] stamp = new int[1];
    String v = ref.get(stamp);
    ref.compareAndSet(v, "v2", stamp[0], stamp[0] + 1);
    System.out.println(ref.getReference());
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;LongAdder / DoubleAdder - high contention counters (metrics)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import java.util.concurrent.atomic.*;

class ExLongAdder {
  public static void main(String[] args) {
    LongAdder adder = new LongAdder();
    adder.increment();
    adder.add(10);
    System.out.println(adder.sum());
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;LongAccumulator / DoubleAccumulator - high contention reductions with custom op&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import java.util.concurrent.atomic.*;

class ExAccumulator {
  public static void main(String[] args) {
    LongAccumulator max = new LongAccumulator(Long::max, Long.MIN_VALUE);
    max.accumulate(10);
    max.accumulate(7);
    System.out.println(max.get());
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;6) Concurrent collections&lt;br&gt;
ConcurrentHashMap - scalable concurrent map, atomic compute operations&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import java.util.concurrent.*;

class ExConcurrentHashMap {
  public static void main(String[] args) {
    ConcurrentHashMap&amp;lt;String, Integer&amp;gt; m = new ConcurrentHashMap&amp;lt;&amp;gt;();
    m.merge("k", 1, Integer::sum);
    System.out.println(m.get("k"));
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ConcurrentSkipListMap / ConcurrentSkipListSet - sorted concurrent structures&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import java.util.concurrent.*;

class ExSkipList {
  public static void main(String[] args) {
    ConcurrentSkipListMap&amp;lt;Integer, String&amp;gt; m = new ConcurrentSkipListMap&amp;lt;&amp;gt;();
    m.put(2, "b");
    m.put(1, "a");
    System.out.println(m.firstEntry());
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;CopyOnWriteArrayList / CopyOnWriteArraySet - many reads, few writes&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import java.util.concurrent.*;

class ExCopyOnWrite {
  public static void main(String[] args) {
    CopyOnWriteArrayList&amp;lt;Integer&amp;gt; list = new CopyOnWriteArrayList&amp;lt;&amp;gt;();
    list.add(1);
    for (Integer v : list) System.out.println(v);
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ConcurrentLinkedQueue / ConcurrentLinkedDeque - lock free queues&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import java.util.concurrent.*;

class ExConcurrentQueue {
  public static void main(String[] args) {
    ConcurrentLinkedQueue&amp;lt;String&amp;gt; q = new ConcurrentLinkedQueue&amp;lt;&amp;gt;();
    q.add("a");
    System.out.println(q.poll());
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;7) Blocking queues (often used with ThreadPoolExecutor)&lt;br&gt;
ArrayBlockingQueue - bounded FIFO, backpressure&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import java.util.concurrent.*;

class ExArrayBlockingQueue {
  public static void main(String[] args) throws Exception {
    BlockingQueue&amp;lt;Integer&amp;gt; q = new ArrayBlockingQueue&amp;lt;&amp;gt;(1);
    q.put(1);
    System.out.println(q.take());
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;LinkedBlockingQueue - optionally bounded, common default&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import java.util.concurrent.*;

class ExLinkedBlockingQueue {
  public static void main(String[] args) throws Exception {
    BlockingQueue&amp;lt;String&amp;gt; q = new LinkedBlockingQueue&amp;lt;&amp;gt;(10);
    q.offer("x");
    System.out.println(q.poll(1, TimeUnit.SECONDS));
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;SynchronousQueue - zero capacity handoff between producer and consumer&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
import java.util.concurrent.*;

class ExSynchronousQueue {
  public static void main(String[] args) {
    SynchronousQueue&amp;lt;String&amp;gt; q = new SynchronousQueue&amp;lt;&amp;gt;();

    new Thread(() -&amp;gt; {
      try { System.out.println("took " + q.take()); } catch (InterruptedException ignored) {}
    }).start();

    try { q.put("handoff"); } catch (InterruptedException ignored) {}
  }
}
PriorityBlockingQueue - priority ordered tasks/items (usually unbounded)
import java.util.concurrent.*;

class ExPriorityBlockingQueue {
  public static void main(String[] args) throws Exception {
    PriorityBlockingQueue&amp;lt;Integer&amp;gt; q = new PriorityBlockingQueue&amp;lt;&amp;gt;();
    q.put(5);
    q.put(1);
    System.out.println(q.take());
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;DelayQueue - delayed availability items (for scheduling patterns)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicLong;

class ExDelayQueue {
  static final AtomicLong SEQ = new AtomicLong();

  static final class Item implements Delayed {
    final long runAtNanos;
    final long seq = SEQ.incrementAndGet();
    Item(long delayMs) {
      this.runAtNanos = System.nanoTime() + TimeUnit.MILLISECONDS.toNanos(delayMs);
    }
    @Override public long getDelay(TimeUnit unit) {
      return unit.convert(runAtNanos - System.nanoTime(), TimeUnit.NANOSECONDS);
    }
    @Override public int compareTo(Delayed o) {
      Item other = (Item) o;
      int c = Long.compare(this.runAtNanos, other.runAtNanos);
      return (c != 0) ? c : Long.compare(this.seq, other.seq);
    }
  }

  public static void main(String[] args) throws Exception {
    DelayQueue&amp;lt;Item&amp;gt; q = new DelayQueue&amp;lt;&amp;gt;();
    q.put(new Item(200));
    q.take();
    System.out.println("released");
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;LinkedTransferQueue / TransferQueue - high throughput queue with transfer capability&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import java.util.concurrent.*;

class ExTransferQueue {
  public static void main(String[] args) {
    TransferQueue&amp;lt;String&amp;gt; q = new LinkedTransferQueue&amp;lt;&amp;gt;();

    new Thread(() -&amp;gt; {
      try { System.out.println("got " + q.take()); } catch (InterruptedException ignored) {}
    }).start();

    q.tryTransfer("x");
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;8) Thread local, random, time&lt;br&gt;
ThreadLocal - per thread context (request id, formatters)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class ExThreadLocal {
  static final ThreadLocal&amp;lt;Integer&amp;gt; TL = ThreadLocal.withInitial(() -&amp;gt; 0);

  public static void main(String[] args) {
    TL.set(123);
    System.out.println(TL.get());
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ThreadLocalRandom - random without contention in multithreaded code&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import java.util.concurrent.*;

class ExThreadLocalRandom {
  public static void main(String[] args) {
    int x = ThreadLocalRandom.current().nextInt(1, 10);
    System.out.println(x);
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;TimeUnit - consistent time conversions and timed waits&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import java.util.concurrent.*;

class ExTimeUnit {
  public static void main(String[] args) {
    System.out.println(TimeUnit.SECONDS.toMillis(2));
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;9) Classic thread primitives (still used)&lt;br&gt;
Thread + UncaughtExceptionHandler - manual threads, catch uncaught failures&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class ExThreadHandler {
  public static void main(String[] args) {
    Thread t = new Thread(() -&amp;gt; { throw new RuntimeException("boom"); });
    t.setUncaughtExceptionHandler((th, ex) -&amp;gt; System.out.println(th.getName() + " -&amp;gt; " + ex.getMessage()));
    t.start();
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;synchronized + wait()/notifyAll() - intrinsic monitor coordination&lt;/p&gt;

</description>
      <category>java</category>
    </item>
  </channel>
</rss>
