Working with Multithreading
1. Creating Threads
Example: Thread creation
// Subclass
class Worker extends Thread { public void run() { ... } }
new Worker().start();
// Runnable (preferred)
Thread t = new Thread(() -> doWork(), "worker-1");
t.start();
| Approach | Detail |
Extend Thread | Single inheritance limitation |
Implement Runnable | Preferred — separates task from thread |
Implement Callable | Returns value, throws checked exception |
2. Implementing Runnable Interface
| Aspect | Detail |
| Method | void run() |
| Functional interface | Use lambda |
| Reusable | Pass to Thread/Executor |
3. Implementing Callable Interface
| Aspect | Detail |
| Method | V call() throws Exception |
| Returns | Submit to executor → Future<V> |
4. Understanding Thread Lifecycle
| State | Trigger |
| NEW | Created, not started |
| RUNNABLE | Started or running |
| BLOCKED | Waiting for monitor lock |
| WAITING | wait(), join() w/o timeout |
| TIMED_WAITING | sleep(), wait(t) |
| TERMINATED | Run completed |
5. Using Thread Methods (start, sleep, join)
| Method | Detail |
start() | Begin execution (call once) |
sleep(ms) | Static; pauses current thread |
join() / join(ms) | Wait for thread to finish |
yield() | Hint to scheduler (advisory) |
currentThread() | Static; access caller |
6. Setting Thread Priority
| Constant | Value |
MIN_PRIORITY | 1 |
NORM_PRIORITY | 5 (default) |
MAX_PRIORITY | 10 |
| Note | OS-dependent and unreliable |
7. Creating Daemon Threads
| Aspect | Detail |
| Set | t.setDaemon(true) before start |
| Behavior | JVM exits when only daemons remain |
| Use | Background services, monitoring |
8. Interrupting Threads
| Method | Detail |
interrupt() | Signal interruption |
isInterrupted() | Check (does not clear) |
Thread.interrupted() | Static; clears flag |
| Effect on blocking | InterruptedException thrown (clears flag) |
Warning: Never swallow InterruptedException silently — re-throw or restore via Thread.currentThread().interrupt().
9. Handling InterruptedException
Example: Handle interruption
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt(); // restore flag
return; // exit gracefully
}
| Approach | Use |
| Re-throw | Propagate up |
| Restore flag | If can't propagate |
10. Setting Thread Names
| Method | Use |
| Constructor | new Thread(r, "worker") |
setName(s) | Change after creation |
| Benefit | Easier debugging in stack traces |
11. Using ThreadGroup
| Aspect | Detail |
| Status | Largely deprecated for management |
| Replacement | Executors / structured concurrency |
12. Understanding Thread Safety
| Aspect | Detail |
| Definition | Class works correctly under concurrent access |
| Strategies | Immutability, confinement, synchronization, atomics, concurrent collections |
13. Identifying Race Conditions
| Type | Detail |
| Read-modify-write | e.g., counter++ (not atomic) |
| Check-then-act | e.g., null check before init |
| Detection | Stress tests, JCStress, ThreadSanitizer |