Hey there, Java enthusiasts! Welcome to a journey through the world of thread in Java. If you’re anything like me, you’ve probably wondered how to juggle multiple tasks within your Java applications simultaneously. Well, you’re in luck because that’s what I am diving into today – threads! Before we start, don’t worry if you’re new to this. I will take it step by step, from the basics to some pretty nifty tricks. Whether you’re a coding newbie or a seasoned pro looking to brush up on your thread-handling skills, this guide has something for everyone.

What is a Thread in Java?

A thread in Java is the direction or path taken while a program is being executed.

Typically, all programs start with at least one thread, the main thread, which the Java Virtual Machine (JVM) provides when the program begins. When this main thread starts, it kicks off the main() method.

Think of a thread as a program’s action pathway. The Java Virtual Machine allows Java programs to run multiple action pathways simultaneously. Threads have different priorities; higher-priority threads get to do their tasks before lower-priority ones.

Threads are crucial in a program because they allow multiple actions within a single method. Each thread often has a “to-do list,” memory space (like a notebook), and personal workspace for tasks. This way, threads help programs do many things simultaneously, making them efficient and responsive.

How to create a Thread in Java?

Here’s a step-by-step guide to creating and using threads in Java using two standard methods: extending the java.lang.Thread class and implementing the Runnable interface.

Thead in Java

Method 1: Extending Java.lang.Thread class

This method involves extending the Thread class and overriding its run method.

Step 1: Create a new class that extends the Thread class.

public class MyThread extends Thread { // Your thread-specific code will go here }

Step 2: Create an instance of your custom thread class.

MyThread myThread = new MyThread();

Step 3: Implement the functionality you want the thread to execute within the run method.

public void run() { // Your thread’s task or actions go here }

Method 2: Implementing Runnable Interface

This method involves creating a class that implements the Runnable interface and overriding its run method.

Step 1: Create a class.

public class MyRunnable implements Runnable { // Your thread-specific code will go here }

Step 2: Implement the run method within your class.

public void run() { // Your thread’s task or actions go here }

Using these two methods to create and start threads

Now, let’s see an example of how to use these methods to create and start a Thread in Java:

public class ThreadDemo { public static void main(String[] args) { // Method 1: Extending Thread class MyThread myThread = new MyThread(); myThread.start(); // Start the thread // Method 2: Implementing Runnable interface MyRunnable myRunnable = new MyRunnable(); Thread thread = new Thread(myRunnable); thread.start(); // Start the thread } }

In this example, we’ve created instances of both MyThread and MyRunnable, and we’ve started the threads using the start() method. The code you want the threads to execute should be placed inside the run methods of your custom thread classes (MyThread and MyRunnable).

This allows your Java program to perform multiple tasks concurrently, making it more efficient and responsive.

Life cycle of Thread in Java

The life cycle of a thread in Java can be divided into several states, each representing a specific stage in the thread’s execution. Understanding the thread life cycle is essential for effective multithreading.

Start | New State | v Runnable State | v Running State | v Blocked/Waiting State | v Dead State | v Terminated State | End

There are basically 4 stages in the lifecycle of a thread, as given below:

  1. New
  2. Runnable
  3. Running
  4. Blocked (Non-runnable state)
  5. Dead
  1. New − The life cycle of a new thread starts in the new state. It stays in this state until the thread is started by the software. It is additionally referred to as a born thread.
  2. Runnable − A freshly created thread becomes runnable after it has been initiated. When a thread is in this position, it is said to be working on its task.
  3. Waiting −When a thread is waiting for another thread to finish a task, the thread occasionally enters the waiting state. Only when another thread instructs the waiting thread to carry on executing does a thread return to the runnable state.
  4. Timed Waiting −A runnable thread has the option of going into the timed waiting state for a set period of time. When the event it is waiting for occurs or when the time period it is waiting for expires, a thread in this state returns to the runnable state.
  5. Terminated (Dead) − A runnable thread enters the terminated state when it completes its task or otherwise terminates.

How to insert Thread communication in Java

In this example, we’ll demonstrate thread communication using a simple producer-consumer scenario, where one thread produces data, and another thread consumes it. We’ll employ the wait() and notify() methods for synchronization.

Communicating Thread in Java

1. Identify Shared Data

In our scenario, the shared data is a shared buffer where the producer places data, and the consumer retrieves it. We’ll use a simple integer buffer as our shared data structure.

class SharedBuffer { private int data; private boolean dataAvailable = false; // Methods for producing and consuming data will be implemented here. }

2. Choose Synchronization Mechanisms

We’ll use the synchronized keyword along with the wait() and notify() methods for synchronization. This combination ensures the producer and consumer can safely communicate and coordinate their actions.

3. Define Thread Roles

  • Producer Thread: Responsible for producing data and notifying the consumer when data is available.
  • Consumer Thread: Responsible for consuming data and notifying the producer when it can accept more data.

4. Implement Communication Logic

Let’s implement the communication logic within the SharedBuffer class:

class SharedBuffer { private int data; private boolean dataAvailable = false; public synchronized void produce(int value) { while (dataAvailable) { try { wait(); // Wait if data is already available } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } data = value; dataAvailable = true; notify(); // Notify the waiting consumer } public synchronized int consume() { while (!dataAvailable) { try { wait(); // Wait if data is not available } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } dataAvailable = false; notify(); // Notify the waiting producer return data; } }

5. Handle Errors and Exceptions

In this example, we handle InterruptedException to ensure that thread interruptions are properly managed.

6. Thorough Testing

To test our producer-consumer scenario, we’ll create producer and consumer threads and have them interact with the SharedBuffer. Here’s a simplified example:

public class Main { public static void main(String[] args) { SharedBuffer buffer = new SharedBuffer(); Thread producerThread = new Thread(() -> { for (int i = 1; i { for (int i = 1; i <= 5; i++) { int consumedValue = buffer.consume(); System.out.println(“Consumed: ” + consumedValue); } }); producerThread.start(); consumerThread.start(); } }

This code creates a producer thread and a consumer thread that communicate through the SharedBuffer. The producer produces values, and the consumer consumes them, ensuring proper synchronization using wait() and notify().

Following these steps and understanding the example, you can effectively implement thread communication in your Java programs.

Java Thread Priorities

The number of services assigned to a given thread is its priority. In the JVM, every thread is assigned a priority on a scale from 1 to 10, where:

1 is the lowest priority.
5 is the standard priority.
10 represents the highest priority.

By default, the main thread’s priority is set to 5, and each child thread inherits its parent thread’s priority. You can adjust a thread’s priority using the Thread class’s constants:

Thread.MIN_PRIORITY

Thread.NORM_PRIORITY

Thread.MAX_PRIORITY

Here’s a program illustrating Thread Priority:

public class ThreadPriorityExample { public static void main(String[] args) { Thread thread1 = new Thread(() -> { // Thread logic here }); Thread thread2 = new Thread(() -> { // Thread logic here }); thread1.setPriority(Thread.MIN_PRIORITY); // Lowest priority thread2.setPriority(Thread.MAX_PRIORITY); // Highest priority thread1.start(); thread2.start(); } }

Benefits of learning Java

  • Java proficiency increases your job prospects in high-demand fields like web development, Android app development, and enterprise software.
  • Java is widely used in finance, healthcare, and e-commerce sectors, ensuring its relevance across diverse industries.
  • Mastering Java gives you a competitive edge, a fundamental skill many employers seek for software development roles.
  • Java’s scalability and robustness make it suitable for building large-scale, mission-critical applications, contributing to career growth.
  • Java’s extensive developer community provides access to resources, support, and opportunities for networking and knowledge sharing.

By leveraging Java’s strengths, professionals can enhance their career prospects and contribute to developing robust and scalable software solutions.

Where to Kickstart Your Java Journey

Top Java Learning Institute: Henry Harvin

Henry Harvin Benefits

Here are the benefits of the Henry Harvin Institute Java Program

  • Learn from industry experts with 11+ years of experience.
  • Access comprehensive E-learning resources, including tools, techniques, videos, and assessments.
  • Secure 100% placement assistance for one year post-program completion.
  • Earn a prestigious Hallmark Certification as a Certified Java Developer from a government-recognized and award-winning institute.

Wrapping Up

To sum it up, Thread in Java is like teamwork in programming. By understanding how to create, organize, and coordinate threads, you can make your programs work faster and better. Knowing how to use threads will help you build great software and solve tricky problems as you get better at Java. Ready to start your journey in Java? Join us today!

Top Picks for Reading

What are Data Structures in Java

Top 10 Java Full Stack Developer Courses in India

Top 10 JavaScript Books for 2023

Thread in Java: A Beginner’s Guide

FAQs

Q1) What is the purpose of a thread in Java?

Through the use of threads, software can perform several tasks at once and work more effectively. The usage of threads allows for the background completion of complex tasks without interfering with the main program.

Q2) Can multiple threads exist on one object?

Yes. Threads share memory. It is secure if both threads are reading, but caution must be exercised if either of them writes so that the other thread can read the shared object consistently.

Q3) How many threads can be executed?

One core can only handle the execution of one native CPU thread at once. Only 4 threads, for instance, can be performed simultaneously if you have 4 cores (if you only have 2 threads/core, one thread will execute at a moment, and the second will wait to be executed when the first is finished).

Q4) Can two threads execute two methods?

No, two threads cannot invoke synchronized methods on the same class instance at the same time. As long as the instance is the same, this holds even if the two threads call different methods.

Join the Discussion

Interested in Henry Harvin Blog?
Get Course Membership Worth Rs 6000/-
For Free

Our Career Advisor will give you a call shortly

Someone from India

Just purchased a course

1 minutes ago

Noida Address:

Henry Harvin House, B-12, Sector 6, Noida, Uttar Pradesh 201301

FREE 15min Course Guidance Session:

Henry Harvin Student's Reviews
Henry Harvin Reviews on MouthShut | Henry Harvin Reviews on Ambitionbox |
Henry Harvin Reviews on Glassdoor| Henry Harvin Reviews on Coursereport