Thursday, 12 June 2025

Multi threading And priorityThread in java

 ✅ What is a Thread in Java?

A thread in Java is a lightweight sub-process — the smallest unit of execution. It allows multiple tasks to run concurrently within a program, sharing the same memory space.

Java threads are part of the java.lang.Thread class and can be used to:

  • Perform background tasks

  • Increase responsiveness

  • Utilize CPU more efficiently on multicore systems

✅ What is Multithreading?

Multithreading is the process of executing two or more threads concurrently within a single Java program. It enhances the performance of applications by utilizing CPU more efficiently and enabling tasks to run in parallel.

🔄 Characteristics:

  • Threads share the same memory.

  • Requires synchronization to avoid race conditions.

  • Helps in parallel execution and responsive applications.

✅ Real-world Uses of Multithreading in Projects

Use CaseExample
Web ServersHandling multiple HTTP requests in parallel (Spring Boot, Tomcat)
Background ProcessingAsynchronous email sending, file uploads, or logging
Batch ProcessingProcessing large files or DB records concurrently
UI ResponsivenessIn desktop apps (Swing/JavaFX), long-running tasks run in background threads
Real-time Data ProcessingKafka consumers reading streams on separate threads
MicroservicesRunning parallel tasks (e.g., fetching user info from multiple services)

How many ways create threads in java 8

In Java 8, you can create threads in several ways. The most common approaches are:

1. Extending the Thread Class

You can create a thread by extending the Thread class and overriding its run() method.

class MyThread extends Thread {

    public void run() {

        System.out.println("Thread running...");

    }

}

public class Main {

    public static void main(String[] args) {

        MyThread thread = new MyThread();

        thread.start(); // Start the thread

    }

}

2. Implementing the Runnable Interface

Implementing Runnable allows more flexibility since the class can still extend another class.

class MyRunnable implements Runnable {

    public void run() {

        System.out.println("Thread running...");

    }

}

public class Main {

    public static void main(String[] args) {

        Thread thread = new Thread(new MyRunnable());

        thread.start();

    }

}

3. Using Lambda Expressions (Java 8 Feature)

Java 8 introduced lambda expressions, simplifying the Runnable implementation.

public class Main {

    public static void main(String[] args) {

        Thread thread = new Thread(() -> System.out.println("Thread running..."));

        thread.start();

    }

}

4. Using the ExecutorService (Thread Pool)

Java provides the ExecutorService framework to manage thread pools efficiently.

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

public class Main {

    public static void main(String[] args) {

        ExecutorService executor = Executors.newFixedThreadPool(2);

        executor.submit(() -> System.out.println("Thread running..."));

        executor.shutdown(); // Shutdown the executor

    }

}

5. Using the Callable and Future Interface

If you need a return value from a thread, use Callable instead of Runnable.

import java.util.concurrent.*;

public class Main {

    public static void main(String[] args) {

        ExecutorService executor = Executors.newSingleThreadExecutor();

        Callable<String> task = () -> {

            Thread.sleep(2000); // Simulating a delay

            return "Task completed!";

        };

        Future<String> future = executor.submit(task);

        try {

            System.out.println("Waiting for the result...");

            String result = future.get(); // Blocks until the result is available

            System.out.println("Result: " + result);

        } catch (InterruptedException | ExecutionException e) {

            e.printStackTrace();

        } finally {

            executor.shutdown(); // Properly shut down the executor

        }

    }

}

6. Using CompletableFuture (Java 8 Feature)

Java 8 introduced CompletableFuture for async programming.

import java.util.concurrent.CompletableFuture;

public class Main {

    public static void main(String[] args) {

        CompletableFuture.runAsync(() -> System.out.println("Thread running..."));

    }

}

Each approach has its own use case, depending on whether you need a simple thread, a return value, or a managed thread pool.

✅ Code Recap (Quick Summary)

// 1. Thread class
new MyThread().start();

// 2. Runnable
new Thread(new MyRunnable()).start();

// 3. Lambda Runnable
new Thread(() -> System.out.println("Running")).start();

// 4. ExecutorService
ExecutorService pool = Executors.newFixedThreadPool(2);
pool.submit(() -> System.out.println("Pool thread"));
pool.shutdown();

// 5. Callable + Future
Future<String> future = Executors.newSingleThreadExecutor()
    .submit(() -> "Result");
System.out.println(future.get());

// 6. CompletableFuture
CompletableFuture.runAsync(() -> System.out.println("Async thread"));

✅ Summary Table

FeatureThreadRunnableExecutorCallableCompletableFuture
Return Value❌/✅
Java 8 Friendly
Use for Thread Pools
Async Style
Lambda Support


Where to Use Multithreading in Your Spring Boot Project?

Multithreading is beneficial in various scenarios of a Spring Boot application:

1. Asynchronous Task Execution

Use @Async to run tasks in a separate thread.


import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; @Service public class MyService { @Async public void performTask() { System.out.println("Executing in thread: " + Thread.currentThread().getName()); } }

✅ Use Case: Long-running operations like sending emails, file processing, or background jobs.


2. Parallel Processing in REST APIs

Use CompletableFuture to return responses without blocking.


import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; import java.util.concurrent.CompletableFuture; @Service public class MyService { @Async public CompletableFuture<String> getData() { return CompletableFuture.supplyAsync(() -> "Processing Data..."); } }

✅ Use Case: Fetching data from multiple sources (e.g., APIs, databases) in parallel.


3. Handling Multiple User Requests (Thread Pooling)

Spring Boot uses ExecutorService for thread pooling.


import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import java.util.concurrent.Executor; import java.util.concurrent.Executors; @Configuration public class ThreadPoolConfig { @Bean public Executor taskExecutor() { return Executors.newFixedThreadPool(5); // 5 concurrent threads } }

✅ Use Case: Optimizing performance for high-traffic APIs.


4. Multi-threaded Batch Processing (Spring Batch)

Spring Batch executes tasks in chunks using multiple threads.


import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing; import org.springframework.context.annotation.Configuration; @Configuration @EnableBatchProcessing public class BatchConfig { }

✅ Use Case: Large dataset processing, scheduled jobs, and ETL (Extract, Transform, Load) tasks.


5. Concurrent Database Operations

Using @Transactional with multithreading ensures data consistency.


import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @Service public class MyService { @Transactional public void updateDatabase() { // Perform database operations safely in a multithreaded environment } }

✅ Use Case: Parallel processing of bulk database updates.


Conclusion

Multithreading is a vital concept in Java programming, enabling the concurrent execution of tasks to fully utilize system resources and improve application responsiveness. It plays a key role in:

  • 🔄 Concurrency: Efficiently managing multiple tasks at the same time.

  • Parallelism: Taking advantage of multi-core processors for faster execution.

  • 🚀 Responsiveness: Ensuring that applications remain smooth and non-blocking during long-running operations.

In high-performance Java applications, multithreading is essential for:

  • Optimizing resource utilization

  • Enhancing throughput and scalability

  • Supporting real-time and asynchronous processing

In modern Spring Boot projects, multithreading is widely applied for:

  • Handling multiple HTTP requests concurrently

  • Running background tasks (e.g., email sending, data processing)

  • Performing parallel database operations to reduce latency

By using Java’s threading tools—such as Thread, Runnable, ExecutorService, Callable, and CompletableFuture—developers can write more efficient, robust, and scalable applications.

In Java, thread priorities determine the relative importance of threads, helping the thread scheduler decide which thread to run first when multiple threads are eligible.


2) Thread Priority in Java

  • Every thread in Java has a priority, an integer between 1 (MIN_PRIORITY) and 10 (MAX_PRIORITY).

  • The default priority is 5 (NORM_PRIORITY).


🔢 Priority Constants in Thread class:

public static final int MIN_PRIORITY = 1; public static final int NORM_PRIORITY = 5; public static final int MAX_PRIORITY = 10;

🔧 Setting and Getting Priority:

Thread t = new Thread(); t.setPriority(Thread.MAX_PRIORITY); // Set to 10 int p = t.getPriority(); // Get priority

⚙️ Example with Priority:

class PriorityThread extends Thread { public void run() { System.out.println(Thread.currentThread().getName() + " with priority " + getPriority()); } } public class Main { public static void main(String[] args) { PriorityThread t1 = new PriorityThread(); PriorityThread t2 = new PriorityThread(); PriorityThread t3 = new PriorityThread(); t1.setPriority(Thread.MIN_PRIORITY); // 1 t2.setPriority(Thread.NORM_PRIORITY); // 5 t3.setPriority(Thread.MAX_PRIORITY); // 10 t1.setName("Low Priority"); t2.setName("Normal Priority"); t3.setName("High Priority"); t1.start(); t2.start(); t3.start(); } }

🧠 Output (order is not guaranteed):

Low Priority with priority 1 High Priority with priority 10 Normal Priority with priority 5

The JVM thread scheduler behavior depends on the OS. Java thread priority is a hint, not a strict rule. Don't rely on it for correctness in production code.


🔒 Summary:

FeatureValue
Range1 to 10
Default Priority5 (NORM_PRIORITY)
Used forThread scheduling hints
OS-dependent✅ Yes

No comments:

Post a Comment