Fork/Join Framework হল Java 7 এ যুক্ত একটি শক্তিশালী কনক্যারেন্সি ফিচার যা মাল্টিথ্রেডিংয়ের মাধ্যমে বড় ধরনের কাজগুলো ছোট ছোট টাস্কে ভাগ করে দ্রুত এক্সিকিউট করতে সহায়ক। এটি কার্যকরীভাবে পারালাল প্রসেসিং, ডিভাইড অ্যান্ড কনকার (Divide and Conquer) প্রক্রিয়া এবং মাল্টি-কোর প্রসেসর ব্যবহার করতে সক্ষম। Java 7 এ ForkJoinPool ক্লাসের মাধ্যমে এই ফ্রেমওয়ার্কটি প্রবর্তিত হয়, যা মাল্টিপল থ্রেডগুলোকে একই সময়ে একাধিক কাজ একত্রে সমাধান করার জন্য সমন্বয় করে।
Java 8 এবং পরবর্তী সংস্করণে Fork/Join Framework এর কিছু উন্নত বৈশিষ্ট্য এবং পদ্ধতি যুক্ত করা হয়েছে, যা প্রোগ্রামের পারফরম্যান্স আরও উন্নত করতে সহায়ক।
১. Fork/Join Framework এর মূল ধারণা
Fork/Join Framework মূলত ForkJoinPool ক্লাসের মাধ্যমে কাজ করে, যা একটি থ্রেড পুল ব্যবস্থাপনা করে। থ্রেড পুলের মধ্যে কাজগুলো ভাগ করে (fork) এবং পরবর্তী সময়ে তাদের সমন্বয় করে (join) একত্রিত করা হয়।
এটির মূল ধারণা হল:
- Fork: একটি বড় কাজকে ছোট ছোট কাজ বা টাস্কে ভাগ করা।
- Join: সমস্ত ছোট টাস্কের ফলাফল একত্রিত করা।
ForkJoinPool দুইটি প্রধান কার্যকারিতা দিয়ে কাজ করে:
- RecursiveTask: এটি একটি কাজ যা একটি রিটার্ন ভ্যালু প্রদান করে।
- RecursiveAction: এটি একটি কাজ যা কোনো রিটার্ন ভ্যালু প্রদান করে না (void)।
২. Fork/Join Framework এর উন্নত সংস্করণ
Java 8-এ Fork/Join Framework এর কিছু উন্নতি এবং নতুন ফিচার যুক্ত করা হয়েছে যা পারফরম্যান্স এবং ব্যবহারকারীর অভিজ্ঞতা উন্নত করেছে:
১. Stream API Integration:
Java 8-এ Fork/Join ব্যবস্থাপনা এবং Stream API-এর একটি শক্তিশালী সংযোগ রয়েছে। এটি parallelStream() ব্যবহার করে মাল্টি-থ্রেডিংয়ের মাধ্যমে ডেটা প্রসেসিং করতে সহায়ক। ForkJoinPool এখন Stream.parallel() মেথডের মাধ্যমে স্ট্রিম অপারেশনগুলির পারফরম্যান্স উন্নত করে।
উদাহরণ:
import java.util.*;
import java.util.concurrent.*;
import java.util.stream.*;
public class ForkJoinExample {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
// Parallel Stream using Fork/Join Framework
int sum = numbers.parallelStream().mapToInt(Integer::intValue).sum();
System.out.println("Sum of numbers: " + sum); // Output: Sum of numbers: 55
}
}এখানে parallelStream() স্ট্রিমের মধ্যে Fork/Join Framework ব্যবহার করে ডেটা এক্সিকিউট করেছে। এটি বিভিন্ন থ্রেডে কাজ ভাগ করে দ্রুত ফলাফল প্রদান করে।
২. Custom Work Stealing:
Java 8-এ Work Stealing কৌশলটি আরও উন্নত করা হয়েছে। এখন আপনি ForkJoinPool এর মধ্যে থ্রেডের কাজের ভাগ বদলাতে পারেন (stealing work from other threads) যাতে কোনও থ্রেড অব্যবহৃত না থাকে এবং সবথেকে দ্রুত কাজ করে।
৩. RecursiveTask/RecursiveAction Optimizations:
Java 8-এ RecursiveTask এবং RecursiveAction ক্লাসগুলির পারফরম্যান্স উন্নত করা হয়েছে। এটি বড় কাজগুলিকে ছোট ছোট কাজের মধ্যে ভাগ করার সময় আরও দক্ষতার সাথে কাজ করে, যাতে কাজের ভাগ আরও ভালোভাবে সম্পন্ন হতে পারে এবং পারফরম্যান্স উন্নত হয়।
উদাহরণ:
import java.util.concurrent.RecursiveTask;
public class ForkJoinSumExample extends RecursiveTask<Long> {
private final long[] arr;
private final int low;
private final int high;
public ForkJoinSumExample(long[] arr, int low, int high) {
this.arr = arr;
this.low = low;
this.high = high;
}
@Override
protected Long compute() {
if (high - low <= 1) {
return arr[low]; // Base case: return the element at index low
} else {
int mid = (low + high) / 2;
ForkJoinSumExample left = new ForkJoinSumExample(arr, low, mid);
ForkJoinSumExample right = new ForkJoinSumExample(arr, mid, high);
left.fork(); // Fork the left task
long rightResult = right.compute(); // Compute the right task
long leftResult = left.join(); // Join the left task result
return leftResult + rightResult;
}
}
public static void main(String[] args) {
long[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
ForkJoinPool pool = new ForkJoinPool();
ForkJoinSumExample task = new ForkJoinSumExample(arr, 0, arr.length);
long result = pool.invoke(task);
System.out.println("Sum: " + result); // Output: Sum: 55
}
}এখানে, আমরা একটি অ্যারে এর উপাদানগুলো যোগ করার জন্য RecursiveTask ব্যবহার করছি। যখন উপাদানের সংখ্যা একটি নির্দিষ্ট সীমার নিচে চলে যায়, তখন এটি ফর্ক করার পরিবর্তে সরাসরি ফলাফল প্রদান করে। তবে যখন বড় আকারে কাজ হচ্ছে, তখন এটি কাজগুলো ভাগ করে এবং সমান্তরালভাবে এক্সিকিউট করা হয়।
৩. Improved Scalability:
Java 8-এ ForkJoinPool এর স্কেলেবিলিটি উন্নত করা হয়েছে। নতুন commonPool() মেথড দ্বারা ForkJoinPool ব্যবহারের সময় পুরো সিস্টেমের জন্য একটি কমন পুল তৈরি করা হয়, যাতে একাধিক থ্রেডে কাজ ভাগ করে কার্যকরভাবে পারফরম্যান্স বৃদ্ধি করা যায়।
৪. CompletionService:
Java 8-এ CompletionService ক্লাসটি যুক্ত করা হয়েছে, যা আপনার ForkJoinPool কাজের জন্য সিঙ্ক্রোনাস এবং অ্যাসিঙ্ক্রোনাস কাজের ফলাফল দ্রুত সংগ্রহ করতে সহায়ক। এর মাধ্যমে থ্রেড পুলের মাধ্যমে কাজের ফলাফল দ্রুত পাওয়া যায়।
উদাহরণ:
import java.util.concurrent.*;
public class ForkJoinExampleWithCompletionService {
public static void main(String[] args) throws InterruptedException, ExecutionException {
ExecutorService executor = Executors.newFixedThreadPool(4);
CompletionService<Integer> completionService = new ExecutorCompletionService<>(executor);
// Submitting tasks
for (int i = 0; i < 5; i++) {
final int taskId = i;
completionService.submit(() -> {
TimeUnit.SECONDS.sleep(2); // Simulate some work
return taskId * 2; // Return result
});
}
// Collecting results
for (int i = 0; i < 5; i++) {
Future<Integer> future = completionService.take();
System.out.println("Result: " + future.get());
}
executor.shutdown();
}
}এখানে, ExecutorCompletionService এবং ForkJoinPool এর মাধ্যমে একাধিক কাজ সম্পাদন করা হয়েছে এবং তাদের ফলাফল একে একে সংগ্রহ করা হয়েছে।
সারসংক্ষেপ
- Fork/Join Framework Java 7 এ মাল্টি-কোর প্রসেসর ব্যবহার করে বড় কাজগুলিকে ছোট ছোট টাস্কে ভাগ করার জন্য তৈরি করা হয়েছিল।
- Java 8-এ Fork/Join Framework এর উন্নত সংস্করণ এসেছে, যা Stream API, Custom Work Stealing, RecursiveTask/RecursiveAction অপটিমাইজেশন, এবং CompletionService এর মতো নতুন বৈশিষ্ট্যসমূহ অন্তর্ভুক্ত করেছে।
- এই ফিচারগুলো ব্যবহার করে বড় ডেটা সেট বা কম্প্লেক্স প্রসেসিংয়ের কাজগুলো দ্রুত, কার্যকরভাবে এবং সমান্তরালভাবে সম্পাদন করা যায়।
এগুলো parallelism এবং concurrency বৃদ্ধির মাধ্যমে সিস্টেমের পারফরম্যান্স উন্নত করতে সহায়ক।
Read more