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
)
NEW
RUNNABLE
BLOCKED
WAITING
TIMED_WAITING
TERMINATED
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_PRIORITY
toMAX_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
Callable
when you need task results. - Prefer
ExecutorService
for managing threads. - Minimize use of
synchronized
; use locks or concurrent utilities. - Handle thread interruptions gracefully.
0 Comments