Multi-threaded I/O হল একটি প্রক্রিয়া যেখানে একাধিক থ্রেডের মাধ্যমে ইনপুট এবং আউটপুট অপারেশন সম্পাদন করা হয়, যার মাধ্যমে একাধিক I/O অপারেশন একসাথে সম্পন্ন করা যায়। এটি I/O অপারেশন আরও কার্যকর এবং দ্রুত করতে সহায়ক, কারণ এটি একাধিক থ্রেড ব্যবহার করে I/O কাজকে параллেল (parallel)ভাবে সম্পন্ন করতে পারে।
Multi-threaded I/O এর সুবিধা:
- Improved Performance: একাধিক থ্রেড ব্যবহার করে একাধিক I/O অপারেশন একসাথে সম্পাদিত হওয়ার কারণে পারফরম্যান্স উন্নত হয়।
- Non-blocking I/O: এক থ্রেডের অপেক্ষা না করে অন্য থ্রেডে কাজ চালানো যায়।
- Concurrency: একাধিক I/O অপারেশন একই সময়ে করা সম্ভব।
Multi-threaded I/O বাস্তবায়ন
Scenario:
ধরা যাক, আমাদের দুটি ফাইল থেকে ডেটা পড়ে একটি নতুন ফাইলে লিখতে হবে, এবং এই কাজটি আমরা Multi-threading ব্যবহার করে কার্যকরভাবে করতে চাই।
উদাহরণ:
এই উদাহরণে, দুটি ফাইল থেকে ডেটা পড়ার জন্য দুটি আলাদা থ্রেড তৈরি করা হবে, এবং তাদের আউটপুট একটি তৃতীয় ফাইলে লেখা হবে।
import java.io.*;
import java.util.concurrent.*;
public class MultiThreadedIOExample {
public static void main(String[] args) throws InterruptedException, ExecutionException {
// ExecutorService to manage threads
ExecutorService executor = Executors.newFixedThreadPool(2);
// File paths for reading data
String file1Path = "file1.txt";
String file2Path = "file2.txt";
String outputFilePath = "mergedOutput.txt";
// Submit tasks for reading data from file1 and file2
Future<String> file1Data = executor.submit(new FileReaderTask(file1Path));
Future<String> file2Data = executor.submit(new FileReaderTask(file2Path));
// Wait for both threads to finish and get the data
String dataFromFile1 = file1Data.get();
String dataFromFile2 = file2Data.get();
// Write the merged data into the output file
try (BufferedWriter writer = new BufferedWriter(new FileWriter(outputFilePath))) {
writer.write(dataFromFile1);
writer.write("\n");
writer.write(dataFromFile2);
System.out.println("Data from both files merged successfully!");
} catch (IOException e) {
e.printStackTrace();
}
// Shut down the executor
executor.shutdown();
}
// Task for reading a file and returning the data
static class FileReaderTask implements Callable<String> {
private String filePath;
public FileReaderTask(String filePath) {
this.filePath = filePath;
}
@Override
public String call() throws IOException {
StringBuilder fileContent = new StringBuilder();
try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) {
String line;
while ((line = reader.readLine()) != null) {
fileContent.append(line).append("\n");
}
}
return fileContent.toString();
}
}
}
ব্যাখ্যা:
- ExecutorService:
- এখানে আমরা একটি
ExecutorServiceব্যবহার করছি যা থ্রেড ম্যানেজমেন্টের জন্য ব্যবহার করা হয়। এটি আমাদের দুটি থ্রেড একসাথে চালাতে সাহায্য করে।
- এখানে আমরা একটি
- FileReaderTask:
- এটি একটি
Callableটাস্ক যা ফাইল থেকে ডেটা পড়ে।Callableব্যবহার করা হয়েছে কারণ এটিFutureঅবজেক্ট রিটার্ন করে, যা থ্রেডের কাজ শেষ হওয়ার পর ডেটা ফেরত দেয়।
- এটি একটি
- Multi-threading:
- আমরা দুটি থ্রেড সাবমিট করেছি যাতে একে অপরের সাথে প্যারালেলভাবে কাজ করতে পারে এবং দুটি ফাইল থেকে ডেটা পড়ে, পরে সেই ডেটা একটি তৃতীয় ফাইলে লিখে।
- BufferedWriter:
- শেষে, আমরা
BufferedWriterব্যবহার করেছি মেমরি-ভিত্তিক আউটপুট স্ট্রীমে ডেটা লিখতে। দুটি ফাইলের ডেটা একত্রিত করে একটি নতুন ফাইলে লেখা হচ্ছে।
- শেষে, আমরা
Future.get():- থ্রেডের আউটপুট আসার জন্য
Future.get()ব্যবহার করা হয়েছে, যা থ্রেডের কাজ শেষ হওয়া পর্যন্ত অপেক্ষা করে।
- থ্রেডের আউটপুট আসার জন্য
- Shutdown Executor:
executor.shutdown()ব্যবহার করে থ্রেডের এক্সিকিউশন বন্ধ করা হয়েছে।
আউটপুট:
ধরা যাক, file1.txt এবং file2.txt ফাইলগুলির মধ্যে কিছু টেক্সট রয়েছে। এই উদাহরণে, তাদের ডেটা mergedOutput.txt ফাইলে একত্রিত করা হবে।
file1.txt:
Hello from file 1.
file2.txt:
Hello from file 2.
mergedOutput.txt:
Hello from file 1.
Hello from file 2.
Multi-threaded I/O এর সুবিধা:
- বাড়তি পারফরম্যান্স: একাধিক I/O অপারেশন একে অপরের সাথে প্যারালেলভাবে করা যায়, যার ফলে কাজ দ্রুত হয়ে যায়।
- Non-blocking I/O: এক থ্রেডের অপেক্ষা না করে অন্য থ্রেডে কাজ চালানো যায়।
- Concurrency: একাধিক থ্রেড একসাথে কাজ করতে পারে, যা মেমরি ব্যবহারে কার্যকরী।
Multi-threaded I/O এর সীমাবদ্ধতা:
- Synchronization Issues: একাধিক থ্রেডের মধ্যে সিঙ্ক্রোনাইজেশন সমস্যা হতে পারে যদি প্রয়োজনীয় সিঙ্ক্রোনাইজেশন ঠিকভাবে না করা হয়।
- Complexity: কোডে মাল্টি-থ্রেডিং যুক্ত করার ফলে সমস্যা বা বাগ সৃষ্টির সম্ভাবনা বাড়তে পারে।
- Resource Intensive: অনেক থ্রেড চালানোর জন্য যথেষ্ট রিসোর্স (যেমন CPU, মেমরি) প্রয়োজন।
- Multi-threaded I/O আমাদের I/O অপারেশনকে দ্রুত এবং দক্ষভাবে সম্পাদন করতে সহায়ক। একাধিক থ্রেড ব্যবহার করে আমরা একাধিক ফাইলের ডেটা একযোগে পড়তে এবং লিখতে পারি।
- এই প্রক্রিয়া অনেক বড় ডেটাসেট বা একাধিক ফাইলের জন্য কার্যকর।
- তবে, মাল্টি-থ্রেডিংয়ের সাথে কাজ করার সময় সঠিক synchronization এবং resource management নিশ্চিত করা গুরুত্বপূর্ণ।