What is a Thread in Java?
A thread is a lightweight sub-process and the smallest unit of processing in a program. In Java, a thread allows concurrent execution of two or more parts of a program, achieving multitasking.
Key Concepts
Process vs. Thread
- Process: A program in execution, with its own memory space.
- Thread: A subset of a process; shares the same memory and resources.
Creating Threads
1. Extending Thread Class
class MyThread extends Thread {
public void run() {
System.out.println("Thread is running");
}
}
public class Test {
public static void main(String[] args) {
MyThread thread = new MyThread();
thread.start(); // Starts the thread and invokes the run() method
}
}
2. Implementing Runnable Interface
class MyRunnable implements Runnable {
public void run() {
System.out.println("Thread is running");
}
}
public class Test {
public static void main(String[] args) {
Thread thread = new Thread(new MyRunnable());
thread.start();
}
}
3. Using Callable and Future (Returns a Result)
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
class MyCallable implements Callable<String> {
public String call() {
return "Thread executed";
}
}
public class Test {
public static void main(String[] args) throws Exception {
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<String> future = executor.submit(new MyCallable());
System.out.println(future.get()); // Retrieves the result of the Callable
executor.shutdown();
}
}
Thread Lifecycle
- New: Thread object is created, e.g.,
Thread t = new Thread();. - Runnable: Thread is ready to run after
start()is invoked but waiting for CPU time. - Running: Thread is executing.
- Waiting/Blocked: Thread is waiting for a resource or signal.
- Terminated: Thread completes its task or is stopped.
Thread States (Thread.State)
NEWRUNNABLEBLOCKEDWAITINGTIMED_WAITINGTERMINATED
Thread Methods
Important Methods
start(): Starts a new thread.run(): Entry point for thread execution (override this).sleep(milliseconds): Pauses the thread for a given time.join(): Waits for a thread to die.yield(): Hints to the scheduler to give other threads CPU time.interrupt(): Interrupts a sleeping or waiting thread.isAlive(): Checks if a thread is still running.
Synchronization in Threads
Why Synchronization?
Threads share resources (like variables or objects), leading to data inconsistency if accessed simultaneously.
How to Synchronize?
- Synchronized Block
synchronized(object) { // Critical section } - Synchronized Method
public synchronized void method() { // Critical section } - Static Synchronization
public static synchronized void staticMethod() { // Critical section }
Thread Communication
Methods for Inter-thread Communication
wait(): Causes a thread to wait until another thread invokesnotify().notify(): Wakes up a single thread waiting on this object's monitor.notifyAll(): Wakes up all threads waiting on this object's monitor.
class SharedResource {
synchronized void printMessage() {
try {
wait(); // Waiting for notification
System.out.println("Message received");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
synchronized void notifyThread() {
notify(); // Notifies the waiting thread
}
}
Concurrency Utilities (java.util.concurrent)
Executor Framework
ExecutorService executor = Executors.newFixedThreadPool(2);
executor.execute(() -> System.out.println("Thread executed"));
executor.shutdown();
Locks
ReentrantLock lock = new ReentrantLock();
lock.lock();
try {
// Critical section
} finally {
lock.unlock();
}
Thread-Safe Collections
Examples: ConcurrentHashMap, CopyOnWriteArrayList, etc.
Advanced Topics
- Daemon Threads: Background threads that die when the main thread ends.
thread.setDaemon(true); - Thread Priority:
setPriority(int)(fromMIN_PRIORITYtoMAX_PRIORITY). - Thread Pools: Managing multiple threads efficiently using
ExecutorService. - ForkJoin Framework: Recursive task execution for parallelism.
- Deadlock: Two threads block each other by holding resources the other needs.
Best Practices
- Avoid manually creating too many threads; use thread pools.
- Use
Callablewhen you need task results. - Prefer
ExecutorServicefor managing threads. - Minimize use of
synchronized; use locks or concurrent utilities. - Handle thread interruptions gracefully.




0 Comments