Introduction
The Thread
class in Java is the primary mechanism for creating and managing threads. Each thread represents a separate path of execution within a program, enabling concurrent operations and improving application performance and responsiveness.
Table of Contents
- Overview of Thread Class
- Creating Threads
- Extending the
Thread
Class - Implementing the
Runnable
Interface
- Extending the
- Thread Lifecycle
- Thread Methods
- Example: Extending Thread Class
- Example: Implementing Runnable Interface
- Thread Priorities
- Thread Synchronization
- Inter-Thread Communication
- Thread States
- Daemon Threads
- Conclusion
1. Overview of Thread Class
The Thread
class in Java is part of the java.lang
package and provides constructors and methods to create and manage threads. Threads allow a program to operate more efficiently by performing multiple tasks simultaneously.
Key Methods in Thread Class:
start()
: Starts the execution of the thread.run()
: Contains the code that constitutes the new thread.sleep(long millis)
: Puts the thread to sleep for a specified time.join()
: Waits for the thread to die.interrupt()
: Interrupts the thread.isAlive()
: Tests if the thread is alive.getName()
: Returns the name of the thread.setName(String name)
: Changes the name of the thread.getPriority()
: Returns the priority of the thread.setPriority(int priority)
: Changes the priority of the thread.
2. Creating Threads
Extending the Thread
Class
One way to create a thread is by extending the Thread
class and overriding its run
method.
Example:
class MyThread extends Thread {
@Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName() + " is running. Count: " + i);
try {
Thread.sleep(1000); // Simulate some work with sleep
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Implementing the Runnable
Interface
Another way to create a thread is by implementing the Runnable
interface. This approach is preferred when the class is already extending another class.
Example:
class MyRunnable implements Runnable {
@Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName() + " is running. Count: " + i);
try {
Thread.sleep(1000); // Simulate some work with sleep
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
3. Thread Lifecycle
A thread in Java goes through various states in its lifecycle:
- New: A thread is created but not yet started.
- Runnable: A thread is ready to run and waiting for CPU time.
- Running: A thread is executing.
- Blocked: A thread is blocked waiting for a monitor lock.
- Waiting: A thread is waiting indefinitely for another thread to perform a particular action.
- Timed Waiting: A thread is waiting for another thread to perform a particular action within a stipulated amount of time.
- Terminated: A thread has completed its execution.
4. Thread Methods
start()
Starts the execution of the thread. The JVM calls the run()
method of this thread.
thread.start();
run()
If a thread was constructed using a separate Runnable
object, then that Runnable
object's run
method is called; otherwise, this method does nothing and returns.
public void run() {
// code to be executed
}
sleep()
Puts the current thread to sleep for a specified amount of time.
Thread.sleep(1000); // Sleeps for 1 second
join()
Waits for the thread to die.
thread.join();
interrupt()
Interrupts the thread.
thread.interrupt();
isAlive()
Tests if the thread is alive.
thread.isAlive();
getName() and setName()
Gets or sets the name of the thread.
String name = thread.getName();
thread.setName("New Thread Name");
getPriority() and setPriority()
Gets or sets the priority of the thread.
int priority = thread.getPriority();
thread.setPriority(Thread.MAX_PRIORITY);
5. Example: Extending Thread Class
Example:
class MyThread extends Thread {
@Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName() + " is running. Count: " + i);
try {
Thread.sleep(1000); // Simulate some work with sleep
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
MyThread thread1 = new MyThread();
MyThread thread2 = new MyThread();
thread1.start();
thread2.start();
}
}
Output:
Thread-0 is running. Count: 0
Thread-1 is running. Count: 0
Thread-0 is running. Count: 1
Thread-1 is running. Count: 1
Thread-0 is running. Count: 2
Thread-1 is running. Count: 2
Thread-0 is running. Count: 3
Thread-1 is running. Count: 3
Thread-0 is running. Count: 4
Thread-1 is running. Count: 4
6. Example: Implementing Runnable Interface
Example:
class MyRunnable implements Runnable {
@Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName() + " is running. Count: " + i);
try {
Thread.sleep(1000); // Simulate some work with sleep
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
MyRunnable myRunnable = new MyRunnable();
Thread thread1 = new Thread(myRunnable);
Thread thread2 = new Thread(myRunnable);
thread1.start();
thread2.start();
}
}
Output:
Thread-0 is running. Count: 0
Thread-1 is running. Count: 0
Thread-0 is running. Count: 1
Thread-1 is running. Count: 1
Thread-0 is running. Count: 2
Thread-1 is running. Count: 2
Thread-0 is running. Count: 3
Thread-1 is running. Count: 3
Thread-0 is running. Count: 4
Thread-1 is running. Count: 4
7. Thread Priorities
Thread priorities determine the relative priority of threads. In Java, thread priority is an integer value between 1 (MIN_PRIORITY) and 10 (MAX_PRIORITY), with a default value of 5 (NORM_PRIORITY).
Example:
class MyThread extends Thread {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " with priority " + Thread.currentThread().getPriority() + " is running.");
}
public static void main(String[] args) {
MyThread thread1 = new MyThread();
MyThread thread2 = new MyThread();
thread1.setPriority(Thread.MIN_PRIORITY); // Set priority to 1
thread2.setPriority(Thread.MAX_PRIORITY); // Set priority to 10
thread1.start();
thread2.start();
}
}
Output:
Thread-0 with priority 1 is running.
Thread-1 with priority 10 is running.
8. Thread Synchronization
Synchronization is used to control the access of multiple threads to shared resources. It prevents data inconsistency and race conditions.
Example:
class Counter {
private int count = 0;
public synchronized void increment() {
count++;
}
public int getCount() {
return count;
}
}
public class SynchronizedExample {
public static void main(String[] args) throws InterruptedException {
Counter counter = new Counter();
Runnable task = () -> {
for (int i = 0; i < 1000; i++) {
counter.increment();
}
};
Thread thread1 = new Thread(task);
Thread thread2 = new Thread(task);
thread1.start();
thread2.start();
thread1.join();
thread2.join();
System.out.println("Final count: " + counter.getCount());
}
}
Output:
Final count: 2000
9. Inter-Thread Communication
Inter-thread communication in Java is achieved using wait()
, notify()
, and notifyAll()
methods. These methods are used to synchronize the activities of multiple threads.
Example:
java
class SharedResource {
private int data = 0;
private boolean available = false;
public synchronized void produce(int value) throws InterruptedException {
while (available) {
wait();
}
data = value;
available = true;
notify();
}
public synchronized int consume() throws InterruptedException {
while (!available) {
wait();
}
available = false;
notify();
return data;
}
}
public class InterThreadCommunicationExample {
public static void main(String[] args) {
SharedResource sharedResource = new SharedResource();
Thread producer = new Thread(() -> {
for (int i = 1; i <= 5; i++) {
try {
sharedResource.produce(i);
System.out.println("Produced: " + i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread consumer = new Thread(() -> {
for (int i = 1; i <= 5; i++) {
try {
int value = sharedResource.consume();
System.out.println("Consumed: " + value);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
producer.start();
consumer.start();
}
}
Output:
Produced: 1
Consumed: 1
Produced: 2
Consumed: 2
Produced: 3
Consumed: 3
Produced: 4
Consumed: 4
Produced: 5
Consumed: 5
10. Thread States
A thread in Java can be in one of the following states:
- New: A thread that has been created but not yet started.
- Runnable: A thread that is ready to run and waiting for CPU time.
- Blocked: A thread that is blocked waiting for a monitor lock.
- Waiting: A thread that is waiting indefinitely for another thread to perform a particular action.
- Timed Waiting: A thread that is waiting for another thread to perform a particular action within a specified waiting time.
- Terminated: A thread that has exited.
11. Daemon Threads
Daemon threads are low-priority threads that run in the background to perform tasks such as garbage collection. They do not prevent the JVM from exiting when all user threads finish their execution.
Example:
class MyDaemonThread extends Thread {
@Override
public void run() {
while (true) {
System.out.println("Daemon thread is running.");
try {
Thread.sleep(1000); // Simulate some work with sleep
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
MyDaemonThread daemonThread = new MyDaemonThread();
daemonThread.setDaemon(true); // Set the thread as a daemon thread
daemonThread.start();
try {
Thread.sleep(3000); // Main thread sleeps for 3 seconds
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Main thread is exiting.");
}
}
Output:
Daemon thread is running.
Daemon thread is running.
Daemon thread is running.
Main thread is exiting.
Explanation:
- The
MyDaemonThread
class extendsThread
and overrides therun
method. - The thread is set as a daemon thread using
setDaemon(true)
. - The main thread sleeps for 3 seconds and then exits.
- The daemon thread runs in the background but does not prevent the JVM from exiting.
12. Conclusion
The Thread
class in Java provides a powerful mechanism for creating and managing threads. By extending the Thread
class or implementing the Runnable
interface, you can define tasks that run concurrently. Understanding thread lifecycle, synchronization, inter-thread communication, and daemon threads is essential for writing efficient and robust multithreaded applications.
Happy coding!
Comments
Post a Comment
Leave Comment