I/O Synchronization হল একটি গুরুত্বপূর্ণ কৌশল যখন একাধিক থ্রেড একযোগে I/O অপারেশন পরিচালনা করে। যখন একাধিক থ্রেড একে অপরের সাথে একই রিসোর্স (যেমন একটি ফাইল বা ডাটাবেস) অ্যাক্সেস করে, তখন Thread Safety নিশ্চিত করতে I/O অপারেশনগুলোকে synchronized করা প্রয়োজন।
Java তে I/O Synchronization এর জন্য synchronized blocks বা locks ব্যবহৃত হয়, যাতে এক থ্রেড যখন I/O অপারেশন করছে, তখন অন্য কোন থ্রেড একই রিসোর্স অ্যাক্সেস করতে না পারে এবং data consistency বজায় থাকে।
I/O Synchronization এর প্রয়োজনীয়তা
- Thread Safety: একাধিক থ্রেড যখন একক রিসোর্স (যেমন ফাইল) অ্যাক্সেস করে, তখন তারা একে অপরের সাথে সঠিকভাবে সমন্বয় করতে পারে না। এতে ডেটার ক্ষতি বা ত্রুটি হতে পারে। Synchronization নিশ্চিত করে যে এক থ্রেড যখন একটি রিসোর্স অ্যাক্সেস করবে, তখন অন্য থ্রেড সেই রিসোর্স অ্যাক্সেস করতে পারবে না।
- Data Integrity: যখন একাধিক থ্রেড একসাথে ডেটা প্রক্রিয়া করে, তখন সঠিকভাবে synchronization না হলে ডেটার পরিবর্তন বা অশুদ্ধতা হতে পারে।
- Avoid Deadlocks: Synchronization ব্যবহার করে থ্রেডগুলোর মধ্যে ডেডলক এড়ানো যায়, যেখানে এক থ্রেড অপর থ্রেডের জন্য অপেক্ষা করে এবং কখনও শেষ হয় না।
I/O Synchronization এর কৌশল
I/O Synchronization করার জন্য কয়েকটি কৌশল ব্যবহার করা যায়:
- Synchronized Method:
- কোনো মেথডকে synchronized করা যায় যাতে শুধুমাত্র এক থ্রেড সেই মেথড একসাথে অ্যাক্সেস করতে পারে।
- Synchronized Block:
- synchronized block ব্যবহার করে শুধুমাত্র I/O অপারেশনের প্রয়োজনীয় অংশকে সিঙ্ক্রোনাইজ করা হয়, যা কার্যকারিতা বাড়ায়।
- Locks:
- Java 5 থেকে Lock API ব্যবহৃত হতে পারে যা আরও উন্নত synchronization কৌশল সরবরাহ করে।
I/O Synchronization উদাহরণ
১. Synchronized Method এর মাধ্যমে I/O Synchronization
import java.io.*;
import java.util.concurrent.*;
public class SynchronizedMethodExample {
private static final Object lock = new Object(); // Lock object
public static void main(String[] args) throws InterruptedException {
ExecutorService executor = Executors.newFixedThreadPool(2); // Two threads
// Thread 1: Writes to file
executor.submit(() -> {
synchronized (lock) {
writeToFile("file1.txt", "Thread 1: Writing to file.");
}
});
// Thread 2: Writes to file
executor.submit(() -> {
synchronized (lock) {
writeToFile("file2.txt", "Thread 2: Writing to file.");
}
});
executor.shutdown(); // Shut down the executor
}
// Synchronized I/O method
public static void writeToFile(String fileName, String data) {
try (FileWriter writer = new FileWriter(fileName)) {
writer.write(data);
System.out.println(data + " (Written to " + fileName + ")");
} catch (IOException e) {
e.printStackTrace();
}
}
}
ব্যাখ্যা:
- এখানে
writeToFileমেথডটি synchronized করা হয়েছে, যার মানে এক সময়ে এক থ্রেডই এই মেথডটি অ্যাক্সেস করতে পারবে। ExecutorServiceব্যবহার করা হয়েছে দুটি থ্রেড চালানোর জন্য।- synchronized block ব্যবহার করা হয়েছে যা নিশ্চিত করে যে একে একে ফাইল লেখার কাজ হবে এবং data consistency বজায় থাকবে।
২. Synchronized Block এর মাধ্যমে I/O Synchronization
import java.io.*;
import java.util.concurrent.*;
public class SynchronizedBlockExample {
private static final Object lock = new Object(); // Lock object
public static void main(String[] args) throws InterruptedException {
ExecutorService executor = Executors.newFixedThreadPool(2); // Two threads
// Thread 1: Writes to file
executor.submit(() -> {
writeToFile("file1.txt", "Thread 1: Writing to file.");
});
// Thread 2: Writes to file
executor.submit(() -> {
writeToFile("file2.txt", "Thread 2: Writing to file.");
});
executor.shutdown(); // Shut down the executor
}
// Synchronized I/O method
public static void writeToFile(String fileName, String data) {
synchronized (lock) {
try (FileWriter writer = new FileWriter(fileName)) {
writer.write(data);
System.out.println(data + " (Written to " + fileName + ")");
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
ব্যাখ্যা:
- এখানে
writeToFileমেথডের মধ্যে synchronized block ব্যবহার করা হয়েছে, যাতে একে একে ফাইল লেখার অপারেশন সম্পন্ন হয়। - synchronized block নিশ্চিত করে যে যখন একটি থ্রেড ফাইল লেখছে তখন অন্য থ্রেড সেই ফাইলটি অ্যাক্সেস করতে পারবে না।
৩. Lock ব্যবহার করে I/O Synchronization
import java.io.*;
import java.util.concurrent.*;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class LockExample {
private static final Lock lock = new ReentrantLock(); // Lock object
public static void main(String[] args) throws InterruptedException {
ExecutorService executor = Executors.newFixedThreadPool(2); // Two threads
// Thread 1: Writes to file
executor.submit(() -> {
lock.lock(); // Locking the resource
try {
writeToFile("file1.txt", "Thread 1: Writing to file.");
} finally {
lock.unlock(); // Unlocking the resource
}
});
// Thread 2: Writes to file
executor.submit(() -> {
lock.lock(); // Locking the resource
try {
writeToFile("file2.txt", "Thread 2: Writing to file.");
} finally {
lock.unlock(); // Unlocking the resource
}
});
executor.shutdown(); // Shut down the executor
}
// Synchronized I/O method
public static void writeToFile(String fileName, String data) {
try (FileWriter writer = new FileWriter(fileName)) {
writer.write(data);
System.out.println(data + " (Written to " + fileName + ")");
} catch (IOException e) {
e.printStackTrace();
}
}
}
ব্যাখ্যা:
- এখানে Lock ব্যবহার করা হয়েছে থ্রেডের মধ্যে explicit lock/unlock পরিচালনার জন্য।
lock.lock()ফাইল লেখার আগে lock গ্রহন করা হয়, এবং লেখার পরlock.unlock()দিয়ে lock মুক্ত করা হয়।
I/O Synchronization এর প্রয়োজনীয়তা:
- Thread Safety:
- একাধিক থ্রেড যখন একই রিসোর্স (যেমন ফাইল) অ্যাক্সেস করে, তখন সঠিকভাবে Synchronization নিশ্চিত করা গুরুত্বপূর্ণ। যদি একাধিক থ্রেড একই সময়ে ফাইল লেখার চেষ্টা করে, তাহলে ডেটার অখণ্ডতা নষ্ট হতে পারে।
- Data Consistency:
- I/O Synchronization ডেটার অখণ্ডতা নিশ্চিত করে। একাধিক থ্রেড যখন একই ফাইল বা ডেটা অ্যাক্সেস করে, তখন ডেটার একটানা পরিবর্তন হয়, যা ভুল ডেটা তৈরি করতে পারে।
- Avoiding Race Conditions:
- Race Condition ঘটে যখন একাধিক থ্রেড একে অপরের ডেটা পরিবর্তন করতে থাকে, যার ফলে অবাঞ্ছিত ফলাফল হতে পারে। Synchronization এর মাধ্যমে এই ধরনের সমস্যা থেকে পরিত্রাণ পাওয়া যায়।
- I/O Synchronization নিশ্চিত করার জন্য synchronized methods, synchronized blocks, বা Locks ব্যবহার করা হয়।
- Thread safety এবং data consistency নিশ্চিত করার জন্য এটি একটি অপরিহার্য প্রক্রিয়া।
- Java Tuples ব্যবহার করে synchronized I/O operations এর সাথে সম্পর্কিত প্রোপার্টি যেমন ফাইলের নাম, আকার এবং অন্যান্য তথ্য সংরক্ষণ করা যেতে পারে, যা I/O অপারেশনের ফলাফলকে আরও কার্যকরভাবে ব্যবস্থাপনা করতে সাহায্য করে।
Content added By