yoklainterview sim

Backend Java Concurrency Interview Questions

75 verified Backend Java Concurrency interview questions — solve with answers, learn from explanations, test yourself in a real simulation.

Try the real simulation →

Sample questions

Java ConcurrencyDifficulty 1
Whether you write class Worker extends Thread or class Worker implements Runnable, you must define the code the thread executes by overriding/implementing one method. Which one?
  • astart()
  • bcall()
  • crun()
  • dexecute()
Explanation:Whether a class extends Thread or implements Runnable, the thread's task is defined by overriding/implementing run(). start() launches a new OS thread and internally calls run(); it should never be invoked directly to 'start work'.
Java ConcurrencyDifficulty 2
class DemoThread extends Thread {
    public void run() {
        System.out.println("run: " + Thread.currentThread().getName());
    }
}

public class Main {
    public static void main(String[] args) {
        DemoThread t = new DemoThread();
        t.run();
        System.out.println("main: " + Thread.currentThread().getName());
    }
}

What is printed for the thread name on the first line?
  • amain
  • bA new thread's name, e.g. Thread-0
  • cIt throws IllegalThreadStateException at runtime
  • dnull, because the thread was never started
Explanation:Calling t.run() directly is just an ordinary method invocation — no new thread is created. So Thread.currentThread() inside run() still refers to whichever thread called it, here the main thread, so it prints 'main'. Only t.start() spawns a genuinely new thread.
Java ConcurrencyDifficulty 2
class Counter {
    private int count = 0;
    public void increment() { count++; }
    public int get() { return count; }
}

public class Main {
    public static void main(String[] args) throws InterruptedException {
        Counter counter = new Counter();
        Runnable task = () -> {
            for (int i = 0; i < 100_000; i++) counter.increment();
        };
        Thread t1 = new Thread(task);
        Thread t2 = new Thread(task);
        t1.start(); t2.start();
        t1.join(); t2.join();
        System.out.println(counter.get());
    }
}

What can you say about the final printed value?
  • aIt always prints exactly 200000, with no exceptions
  • bIt throws a ConcurrentModificationException
  • cIt always prints exactly 100000 every single run
  • dNo exact value is guaranteed — because count++ races, it may come out less than 200000
Explanation:count++ is a compound read-modify-write operation, not atomic. When two threads run concurrently without synchronization, updates can interleave and be lost, so no specific final value is guaranteed — the result may come out less than 200000 because of those lost updates.
Java ConcurrencyDifficulty 2
Which statement correctly distinguishes Callable<V> from Runnable?
  • aCallable can only be used with Thread, never with ExecutorService
  • bCallable's call() can return a value and declare a checked exception; run() cannot
  • cThere is no real difference; both are used interchangeably by the compiler
  • dRunnable can return a value from run(), but Callable never can
Explanation:Callable<V>.call() can return a value of type V and is allowed to throw a checked exception. Runnable.run() has a void return type and cannot declare checked exceptions. This is why Callable is used with ExecutorService.submit() when a result or a checked exception needs to be propagated.
Java ConcurrencyDifficulty 2
public class Printer {
    public synchronized void printTicket(int id) {
        System.out.print("[" + id);
        System.out.println("]");
    }
}

Two threads repeatedly call printTicket() on the SAME Printer instance with different ids. What does synchronized guarantee here?
  • aThe two threads run printTicket() truly in parallel for better throughput
  • bIt has no effect unless the field being modified is also declared volatile
  • cEach printTicket() call finishes as one unit before another thread can enter
  • dIt guarantees the ids are printed strictly in ascending numeric order
Explanation:A synchronized instance method acquires the monitor of this before executing and releases it on exit, so concurrent calls to printTicket() on the same instance are serialized — one full call completes before another begins. It says nothing about ordering by id or about running in parallel.
Java ConcurrencyDifficulty 1
ExecutorService pool = Executors.newFixedThreadPool(2);
pool.submit(() -> System.out.println("task 1"));
pool.submit(() -> System.out.println("task 2"));
pool.shutdown();

What does pool.shutdown() do here?
  • aImmediately and forcibly kills the two currently running tasks
  • bBlocks the calling thread indefinitely until the JVM itself exits
  • cSilently removes the two tasks from the pool without running them
  • dRejects new task submissions but lets already-submitted tasks finish
Explanation:ExecutorService.shutdown() initiates an orderly shutdown: previously submitted tasks are executed, but no new tasks are accepted. It does not interrupt running tasks and does not block the calling thread.

Test yourself against the 3300-question Backend bank.

Start interview