Fundamentals 33 min read

Java Thread Interview Questions and Answers with Code Examples

This article provides a comprehensive guide to common Java multithreading interview questions, covering thread ordering with join, lock vs synchronized, read‑write locks, wait vs sleep, blocking queues, producer‑consumer patterns, deadlock detection, thread dumps, thread states, and immutable objects, all illustrated with runnable code samples.

Big Data Technology & Architecture
Big Data Technology & Architecture
Big Data Technology & Architecture
Java Thread Interview Questions and Answers with Code Examples

This article collects a series of typical Java multithreading interview questions and provides detailed answers with code examples, making it a useful reference for developers preparing for technical interviews.

Thread ordering with join

To guarantee that T2 runs after T1 and T3 after T2, the Thread.join() method can be used. Example:

public static void main(String[] args) {
    method01();
    method02();
}

private static void method01() {
    Thread t1 = new Thread(() -> System.out.println("t1 is finished"));
    Thread t2 = new Thread(() -> {
        try { t1.join(); } catch (InterruptedException e) { e.printStackTrace(); }
        System.out.println("t2 is finished");
    });
    Thread t3 = new Thread(() -> {
        try { t2.join(); } catch (InterruptedException e) { e.printStackTrace(); }
        System.out.println("t3 is finished");
    });
    t3.start();
    t2.start();
    t1.start();
}

Lock vs synchronized

The Lock interface offers more flexibility than the synchronized block, such as tryLock, timed lock, interruptible lock, and multiple condition queues. A read‑write cache can be built with ReadWriteLock:

public class ReaderAndWriter<K, V> {
    private final ReadWriteLock lock = new ReentrantReadWriteLock();
    private final Lock readLock = lock.readLock();
    private final Lock writeLock = lock.writeLock();
    private final Map<K, V> map;
    public ReaderAndWriter(Map<K, V> map) { this.map = map; }
    public V put(K key, V value) {
        while (true) {
            if (writeLock.tryLock()) {
                try { System.out.println("put " + key + " = " + value); return map.put(key, value); }
                finally { writeLock.unlock(); }
            }
        }
    }
    public V get(K key) {
        while (true) {
            if (readLock.tryLock()) {
                try { V v = map.get(key); System.out.println("get " + key + " = " + v); return v; }
                finally { readLock.unlock(); }
            }
        }
    }
}

wait vs sleep

The main difference is that Object.wait() releases the monitor lock while Thread.sleep() retains it. wait is used for thread communication; sleep simply pauses execution.

BlockingQueue and producer‑consumer

Java 5 introduced BlockingQueue and several implementations (ArrayBlockingQueue, LinkedBlockingQueue, etc.). A simple producer‑consumer using ArrayBlockingQueue:

public class ProduceAndConsumer {
    public static void main(String[] args) {
        BlockingQueue<Integer> queue = new ArrayBlockingQueue<>(10);
        new Procude(queue).start();
        new Consumer(queue).start();
    }
    static class Procude extends Thread {
        private final BlockingQueue<Integer> q;
        Procude(BlockingQueue<Integer> q) { this.q = q; }
        public void run() {
            while (true) {
                try { Integer i = q.take(); System.out.println("Consume: " + i); }
                catch (InterruptedException e) { e.printStackTrace(); }
            }
        }
    }
    static class Consumer extends Thread {
        private final BlockingQueue<Integer> q;
        Consumer(BlockingQueue<Integer> q) { this.q = q; }
        public void run() {
            Random r = new Random();
            while (true) {
                try { int i = r.nextInt(100); q.put(i); System.out.println("Produce: " + i); Thread.sleep(1000); }
                catch (InterruptedException e) { e.printStackTrace(); }
            }
        }
    }
}

Deadlock example and thread dump analysis

A classic deadlock occurs when two threads acquire locks in opposite order. The following code demonstrates it and shows how a thread dump reveals the circular wait:

public class SimpleDeadLock {
    public static void main(String[] args) {
        Object lockA = new Object();
        Object lockB = new Object();
        new A(lockA, lockB).start();
        new B(lockA, lockB).start();
    }
    static class A extends Thread {
        private final Object a, b;
        A(Object a, Object b) { this.a = a; this.b = b; }
        public void run() {
            synchronized (a) {
                try { Thread.sleep(1000); } catch (InterruptedException e) {}
                synchronized (b) { System.out.println("Hello A"); }
            }
        }
    }
    static class B extends Thread {
        private final Object a, b;
        B(Object a, Object b) { this.a = a; this.b = b; }
        public void run() {
            synchronized (b) {
                try { Thread.sleep(1000); } catch (InterruptedException e) {}
                synchronized (a) { System.out.println("Hello B"); }
            }
        }
    }
}

The thread dump shows each thread waiting for the lock held by the other, confirming the deadlock.

Thread states

The article also outlines the Java thread lifecycle: New, Runnable, Running, Blocked (including object‑wait, lock‑wait, and other blocked states), and Terminated. An illustration image is referenced in the original source.

Immutable objects

Immutable objects cannot change after creation, making them inherently thread‑safe. Guidelines for creating immutable classes are listed, and an example is provided:

public final class ImmutableObjectPerson {
    private final String name;
    private final String sex;
    public ImmutableObjectPerson(String name, String sex) { this.name = name; this.sex = sex; }
    public String getName() { return name; }
    public String getSex() { return sex; }
}

Using immutable objects reduces synchronization overhead, improves performance, and simplifies concurrent programming.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaconcurrencydeadlockThreadmultithreadingLockBlockingQueue
Big Data Technology & Architecture
Written by

Big Data Technology & Architecture

Wang Zhiwu, a big data expert, dedicated to sharing big data technology.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.