🎓 Top 15 Udemy Courses (80-90% Discount): My Udemy Courses - Ramesh Fadatare — All my Udemy courses are real-time and project oriented courses.
▶️ Subscribe to My YouTube Channel (178K+ subscribers): Java Guides on YouTube
▶️ For AI, ChatGPT, Web, Tech, and Generative AI, subscribe to another channel: Ramesh Fadatare on YouTube
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