Exchanger এবং Phaser হল Java এর java.util.concurrent প্যাকেজের দুটি শক্তিশালী ক্লাস যা মাল্টি-থ্রেডেড পরিবেশে থ্রেড সিঙ্ক্রোনাইজেশন এবং পারস্পরিক থ্রেড ইন্টারঅ্যাকশন পরিচালনা করতে ব্যবহৃত হয়। এই ক্লাসগুলির সাথে Atomics ব্যবহারের মাধ্যমে আরও দক্ষ এবং থ্রেড-সেফ কনকারেন্সি অপারেশন পরিচালনা করা যেতে পারে।
Exchanger এবং Atomics
Exchanger ক্লাস দুটি থ্রেডের মধ্যে ডেটা আদান-প্রদান করার জন্য ব্যবহৃত হয়। এটি একটি থ্রেডের জন্য ডেটা প্রস্তুত থাকতে পারে এবং অন্য একটি থ্রেড তখন ডেটা গ্রহণ করার জন্য অপেক্ষা করতে পারে। Exchanger সাধারণত একটি blocking operation হিসেবে কাজ করে, যার মানে হল যে, এক থ্রেড তার ডেটা অন্য থ্রেডের সাথে এক্সচেঞ্জ করার জন্য অপেক্ষা করতে থাকবে যতক্ষণ না অন্য থ্রেডও প্রস্তুত হয়।
Atomics API এর সাথে Exchanger ব্যবহারের মাধ্যমে ডেটা এক্সচেঞ্জ করতে লক-মুক্ত এবং দ্রুত অপারেশন নিশ্চিত করা সম্ভব।
ব্যবহারের উদাহরণ: Exchanger এবং Atomics
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
public class AtomicExchangerExample {
public static void main(String[] args) throws InterruptedException {
Exchanger<AtomicInteger> exchanger = new Exchanger<>();
AtomicInteger value1 = new AtomicInteger(100);
AtomicInteger value2 = new AtomicInteger(200);
// Thread 1: Set value and exchange
Thread thread1 = new Thread(() -> {
try {
System.out.println("Thread 1: Before exchange, value: " + value1.get());
AtomicInteger received = exchanger.exchange(value1);
System.out.println("Thread 1: After exchange, received value: " + received.get());
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
// Thread 2: Set value and exchange
Thread thread2 = new Thread(() -> {
try {
System.out.println("Thread 2: Before exchange, value: " + value2.get());
AtomicInteger received = exchanger.exchange(value2);
System.out.println("Thread 2: After exchange, received value: " + received.get());
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
thread1.start();
thread2.start();
thread1.join();
thread2.join();
}
}
আউটপুট:
Thread 1: Before exchange, value: 100
Thread 2: Before exchange, value: 200
Thread 1: After exchange, received value: 200
Thread 2: After exchange, received value: 100
এখানে, Exchanger ক্লাস দুটি থ্রেডের মধ্যে AtomicInteger অবজেক্ট এক্সচেঞ্জ করছে। থ্রেড ১ প্রথমে value1 পাঠাচ্ছে এবং থ্রেড ২ value2 পাঠাচ্ছে। এর ফলে ডেটা এক্সচেঞ্জ করার জন্য AtomicInteger ব্যবহৃত হচ্ছে, যা atomic operation নিশ্চিত করে।
Phaser এবং Atomics
Phaser একটি উচ্চস্তরের সিঙ্ক্রোনাইজেশন ক্লাস যা মাল্টি-ফেজ কাজের জন্য ব্যবহৃত হয়। এটি মূলত phase-based synchronization সরবরাহ করে, যার মাধ্যমে একাধিক থ্রেড নির্দিষ্ট ফেজে পৌঁছানোর পর পরবর্তী কাজ শুরু করতে পারে। Phaser একটি থ্রেডের জন্য নির্দিষ্ট সময় পর্যন্ত ব্লক করতে পারে অথবা সমস্ত থ্রেড একত্রিত হওয়ার পরে পরবর্তী ধাপে যেতে পারে।
Atomics এর সাথে Phaser ব্যবহারের মাধ্যমে আপনি বিভিন্ন থ্রেডের মধ্যে পারস্পরিক সিঙ্ক্রোনাইজেশন এবং atomic operations পরিচালনা করতে পারেন।
ব্যবহারের উদাহরণ: Phaser এবং Atomics
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
public class AtomicPhaserExample {
public static void main(String[] args) throws InterruptedException {
Phaser phaser = new Phaser(1); // Register main thread
AtomicInteger count = new AtomicInteger(0);
// Thread 1
Thread thread1 = new Thread(() -> {
System.out.println("Thread 1: Starting phase 1");
count.incrementAndGet();
phaser.arriveAndAwaitAdvance(); // Wait for others to reach this point
System.out.println("Thread 1: Finished phase 1");
});
// Thread 2
Thread thread2 = new Thread(() -> {
System.out.println("Thread 2: Starting phase 1");
count.incrementAndGet();
phaser.arriveAndAwaitAdvance();
System.out.println("Thread 2: Finished phase 1");
});
// Thread 3
Thread thread3 = new Thread(() -> {
System.out.println("Thread 3: Starting phase 1");
count.incrementAndGet();
phaser.arriveAndAwaitAdvance();
System.out.println("Thread 3: Finished phase 1");
});
// Start threads
thread1.start();
thread2.start();
thread3.start();
// Main thread waits for others to finish phase 1
phaser.arriveAndAwaitAdvance();
System.out.println("Main Thread: All threads have finished phase 1");
// Now proceed to phase 2
System.out.println("Main Thread: Starting phase 2");
// Synchronize threads to start phase 2
phaser.arriveAndAwaitAdvance();
System.out.println("Main Thread: All threads are starting phase 2");
}
}
আউটপুট:
Thread 1: Starting phase 1
Thread 2: Starting phase 1
Thread 3: Starting phase 1
Thread 1: Finished phase 1
Thread 2: Finished phase 1
Thread 3: Finished phase 1
Main Thread: All threads have finished phase 1
Main Thread: Starting phase 2
Main Thread: All threads are starting phase 2
এখানে Phaser ব্যবহৃত হয়েছে AtomicInteger এর সাথে যাতে থ্রেড গুলি সিঙ্ক্রোনাইজড হয়। arriveAndAwaitAdvance() মেথড ব্যবহার করে প্রত্যেকটি থ্রেড একে অপরের সাথে সিঙ্ক্রোনাইজড হয়ে একযোগভাবে কাজ সম্পন্ন করেছে।
Atomics, Exchanger এবং Phaser এর সুবিধা
- Exchanger:
- দুইটি থ্রেডের মধ্যে ডেটা এক্সচেঞ্জের জন্য ব্যবহৃত হয়।
- Atomics এর সাথে, ডেটা এক্সচেঞ্জে atomic operations ব্যবহৃত হয়, যা থ্রেড সেফ এবং race condition প্রতিরোধ করে।
- Performance এর জন্য দ্রুত এবং লক-মুক্ত।
- Phaser:
- একাধিক থ্রেডকে বিভিন্ন পর্যায়ে সিঙ্ক্রোনাইজড করতে সাহায্য করে।
- Atomics এর সাথে ব্যবহার করলে, থ্রেড সিঙ্ক্রোনাইজেশনে atomic operations নিশ্চিত হয়, যা ডেটার সঠিকতা এবং থ্রেড সেফটি বজায় রাখে।
- বিভিন্ন ফেজে থ্রেডগুলিকে একযোগে কাজ করতে সাহায্য করে।
উপসংহার
Exchanger এবং Phaser হল দুটি শক্তিশালী সিঙ্ক্রোনাইজেশন ক্লাস যা মাল্টি-থ্রেডেড পরিবেশে ডেটা এক্সচেঞ্জ এবং থ্রেড সিঙ্ক্রোনাইজেশন পরিচালনা করে। Atomics এর সাথে এই ক্লাসগুলির ব্যবহার করলে ডেটা atomic operations এর মাধ্যমে সুরক্ষিত থাকে এবং থ্রেড সেফটি নিশ্চিত হয়। এই সংমিশ্রণটি lock-free synchronization এবং high-performance concurrency নিশ্চিত করতে ব্যবহৃত হয়, যা সিস্টেমের পারফরম্যান্স উন্নত করতে সাহায্য করে।