Java 8 এর Concurrency Enhancements

Concurrency Enhancements (কনকারেন্সি উন্নতি) - জাভা (Java 8) - Computer Programming

371

Java 8-এ Concurrency বা Multithreading-এর জন্য বেশ কিছু গুরুত্বপূর্ণ উন্নয়ন (enhancements) আনা হয়েছে, যা প্রোগ্রামিংয়ের সিস্টেমের পারফরম্যান্স, স্কেলেবিলিটি এবং সহজতর করে তোলে। এই নতুন ফিচারগুলির মধ্যে প্রধান দুটি হল java.util.concurrent প্যাকেজের নতুন ক্লাস এবং java.util.stream API তে parallel streams। এগুলির সাহায্যে উন্নত ও কার্যকরী মাল্টিথ্রেডেড প্রোগ্রাম তৈরি করা সম্ভব হয়েছে।

Java 8-এ Concurrency Enhancements মূলত থ্রেড পরিচালনা, সিঙ্ক্রোনাইজেশন এবং কাজের কার্যকরী বিভাজন করতে সহায়তা করে। নিচে Java 8 এর কিছু গুরুত্বপূর্ণ Concurrency Enhancements এবং তার ব্যবহার আলোচনা করা হলো।


১. CompletableFuture API

Java 8-এ CompletableFuture একটি অত্যন্ত গুরুত্বপূর্ণ ফিচার হিসেবে এসেছে, যা অ্যাসিনক্রোনাস অপারেশন এবং ভবিষ্যৎ ফলাফলগুলি (future results) পরিচালনা করতে সহায়তা করে। এর মাধ্যমে non-blocking পদ্ধতিতে একাধিক কাজ একসাথে (asynchronously) করা যেতে পারে এবং এর সাথে বিভিন্ন callback এবং composing tasks করা সম্ভব।

CompletableFuture এর সুবিধা:

  • Asynchronous Programming: এটি অ্যাসিনক্রোনাস অপারেশনগুলি সহজভাবে পরিচালনা করতে সাহায্য করে।
  • Non-blocking I/O: I/O অপারেশনগুলিকে ব্লক না করে পার্শ্ব-প্রতিক্রিয়া করা যায়।
  • Lambda Expressions: এটি lambda expressions এর মাধ্যমে কাজের ফ্লো সহজ করে তোলে।

উদাহরণ:

import java.util.concurrent.CompletableFuture;

public class CompletableFutureExample {
    public static void main(String[] args) throws Exception {
        CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(1000);  // Simulating a long task
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return 42;  // Returning a result
        });

        // Use the result when it's ready
        future.thenAccept(result -> System.out.println("Result: " + result));  // Output: Result: 42

        // Waiting for the future to complete
        future.get();  // Blocks the main thread until the result is ready
    }
}

এখানে, CompletableFuture.supplyAsync() ব্যবহার করা হয়েছে অ্যাসিনক্রোনাস কাজ (long task) চালানোর জন্য। thenAccept() মেথড ব্যবহার করে প্রাপ্ত ফলাফলটি প্রিন্ট করা হয়েছে।


২. ForkJoinPool এবং Parallel Streams

Java 8-এ ForkJoinPool ব্যবহারের মাধ্যমে সহজে parallel processing করা যায়। Java 8 এ parallel streams এর মাধ্যমে ডেটা প্রসেসিং আরও দ্রুত হয় কারণ এটি মাল্টিপল কোর ব্যবহার করে ডেটার উপরে কাজ করে।

Parallel Streams:

parallelStream() মেথড ব্যবহার করে স্ট্রিমের উপাদানগুলোকে parallelly প্রসেস করা হয়, যা অধিক কার্যকরী হয় যখন বড় ডেটাসেটের উপর কাজ করা হয়।

উদাহরণ:

import java.util.Arrays;
import java.util.List;

public class ParallelStreamExample {
    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

        // Parallel Stream
        int sum = numbers.parallelStream()
                          .mapToInt(Integer::intValue)
                          .sum();
        
        System.out.println("Sum of numbers: " + sum);  // Output: 55
    }
}

এখানে, parallelStream() মেথড ব্যবহার করে সংখ্যাগুলির সমষ্টি parallel অপারেশনের মাধ্যমে করা হয়েছে। এটি CPU কোরগুলিকে ব্যবহার করে দ্রুত কাজ সম্পন্ন করে।

ForkJoinPool:

ForkJoinPool মাল্টিপল টাস্ককে সন্নিবেশিত (divide) করে বিভিন্ন থ্রেডে পাঠায়, যাতে বড় টাস্কগুলিকে দ্রুত পারফর্ম করা যায়।

import java.util.concurrent.RecursiveTask;
import java.util.concurrent.ForkJoinPool;

public class ForkJoinPoolExample {
    public static void main(String[] args) {
        ForkJoinPool pool = new ForkJoinPool();

        // Example task: calculating factorial
        RecursiveTask<Integer> task = new FactorialTask(5);
        Integer result = pool.invoke(task);

        System.out.println("Factorial Result: " + result);  // Output: 120
    }
}

class FactorialTask extends RecursiveTask<Integer> {
    private final int number;

    FactorialTask(int number) {
        this.number = number;
    }

    @Override
    protected Integer compute() {
        if (number <= 1) {
            return 1;
        } else {
            FactorialTask subTask = new FactorialTask(number - 1);
            subTask.fork();  // Fork a new task
            return number * subTask.join();  // Combine the result
        }
    }
}

এখানে, ForkJoinPool ব্যবহার করে বড় কাজগুলোকে ছোট টাস্কে ভাগ করা হয়েছে এবং সেগুলোকে আলাদাভাবে প্রক্রিয়া করা হয়েছে। RecursiveTask ব্যবহৃত হয়েছে একটি রিকার্সিভ কাজের জন্য।


৩. Atomic ক্লাস এবং volatile Keyword

Java 8 এ Atomic ক্লাস (যেমন AtomicInteger, AtomicLong) এবং volatile কিওয়ার্ড মাল্টিথ্রেডিং এনভায়রনমেন্টে ডেটা সিঙ্ক্রোনাইজেশন সহজ করেছে। Atomic ক্লাসগুলি একে অপরের সাথে থ্রেড নিরাপদে কাজ করতে সাহায্য করে।

Atomic Variables Example:

import java.util.concurrent.atomic.AtomicInteger;

public class AtomicExample {
    public static void main(String[] args) {
        AtomicInteger atomicInteger = new AtomicInteger(0);
        
        // Increment atomically
        atomicInteger.incrementAndGet();  // Atomically increments the value
        System.out.println("Atomic Integer: " + atomicInteger.get());  // Output: 1
    }
}

এখানে, AtomicInteger ব্যবহার করা হয়েছে যাতে একাধিক থ্রেড একে অপরের সাথে হস্তক্ষেপ না করে মান পরিবর্তন করতে পারে। incrementAndGet() মেথড অ্যাটমিকভাবে মান বৃদ্ধি করে।


৪. Lambda Expressions এবং Concurrency

Java 8 এ Lambda Expressions ব্যবহার করে কোড আরও সহজ এবং পরিষ্কার করা হয়েছে। Lambda এক্সপ্রেশন ব্যবহার করে মাল্টিথ্রেডিং প্রোগ্রামে কাজ করা আরও স্বাভাবিক এবং সহজ হয়েছে।

Lambda এবং ExecutorService:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class LambdaConcurrencyExample {
    public static void main(String[] args) {
        ExecutorService executor = Executors.newFixedThreadPool(2);

        // Lambda Expression for Runnable
        executor.submit(() -> {
            System.out.println("Task 1 is running on thread: " + Thread.currentThread().getName());
        });

        executor.submit(() -> {
            System.out.println("Task 2 is running on thread: " + Thread.currentThread().getName());
        });

        executor.shutdown();
    }
}

এখানে, Lambda Expressions ব্যবহার করে Runnable এর জন্য কোড সহজভাবে লিখিত হয়েছে এবং ExecutorService এর মাধ্যমে বিভিন্ন থ্রেডে কাজগুলো সম্পন্ন করা হয়েছে।


সারসংক্ষেপ

Java 8 এর Concurrency Enhancements মাল্টিথ্রেডিং এবং অ্যাসিনক্রোনাস প্রোগ্রামিংকে আরও সহজ এবং কার্যকরী করেছে। কিছু মূল উন্নতি হলো:

  1. CompletableFuture: অ্যাসিনক্রোনাস অপারেশন এবং ফিউচার রেজাল্ট ম্যানেজ করার জন্য।
  2. ForkJoinPool এবং Parallel Streams: মাল্টি-থ্রেডেড প্রোগ্রামিং এবং ডেটা প্রসেসিংয়ের জন্য প্যারালাল কাজ করা।
  3. Atomic ক্লাস: থ্রেড নিরাপদ ভ্যারিয়েবল ব্যবস্থাপনা।
  4. Lambda Expressions: মাল্টিথ্রেডিং কোড লেখাকে সহজ এবং পরিষ্কার করা।

Java 8-এর এই নতুন Concurrency API মাল্টিথ্রেডিং প্রোগ্রামগুলোকে দ্রুত, কার্যকরী এবং সহজ করার জন্য ব্যবহৃত হচ্ছে।

Content added By
Promotion

Are you sure to start over?

Loading...