Govt Exams
volatile ensures that all threads see the most recent value of a variable (visibility) but does not provide atomicity for compound operations.
Virtual threads (Project Loom) are extremely lightweight and allow creating millions of threads efficiently, unlike platform threads which are limited by OS resources.
Java guarantees that the lock is released when exiting a synchronized block, whether normally or via an exception. This is why synchronized is considered safer than manual lock management.
Thread.stop() is deprecated and unsafe. Modern approaches use either a volatile flag or Thread.interrupt() with proper handling. Both are valid and recommended depending on the scenario.
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.submit(() -> System.out.println("Task 1"));
executor.submit(() -> System.out.println("Task 2"));
executor.shutdown();
newSingleThreadExecutor() creates an executor with exactly one thread. Tasks are queued and executed sequentially in the order submitted. Task 1 will always execute before Task 2.
This is a classic deadlock scenario involving circular wait. Race condition involves competing for resources. Starvation is when a thread never gets the resource. Livelock is when threads keep changing states without progress.
When wait() is called, the thread releases the lock it holds on the object and enters the waiting pool. Another thread can then acquire the lock. The thread re-acquires the lock when notified.
CyclicBarrier is a synchronizer that allows a fixed number of threads to wait for each other at a barrier point. Once all threads reach the barrier, they proceed together. It's reusable (cyclic) unlike CountDownLatch.
notify() randomly selects one waiting thread to wake up, while notifyAll() wakes all waiting threads. notifyAll() is generally safer to avoid missed notifications when multiple threads are waiting on the same condition.
Callable interface returns a result via Future, and ExecutorService.invokeAll() waits for all submitted tasks to complete. This is the standard pattern for parallel task execution with result collection.