Semaphore হলো জাভা কনকারেন্সি প্যাকেজের (java.util.concurrent.Semaphore) একটি টুল, যা থ্রেড সিঙ্ক্রোনাইজেশনের জন্য ব্যবহৃত হয়। এটি একটি নির্দিষ্ট সংখ্যক থ্রেডকে একসাথে কোনো রিসোর্স অ্যাক্সেস করার অনুমতি দেয়।
Semaphore কীভাবে কাজ করে?
- পারমিট (Permits): Semaphore-এ একটি নির্দিষ্ট সংখ্যক পারমিট থাকে। প্রতিটি থ্রেড একটি পারমিট গ্রহণ করে কাজ শুরু করে এবং কাজ শেষে পারমিট মুক্ত করে।
- Acquire & Release: থ্রেড একটি পারমিট পাওয়ার জন্য
acquire()কল করে এবং কাজ শেষেrelease()কল করে।
Semaphore এর বাস্তব ব্যবহার
১. থ্রেড সিঙ্ক্রোনাইজেশন:
উদাহরণ: একটি রিসোর্সে সর্বাধিক ২টি থ্রেড কাজ করতে পারবে।
import java.util.concurrent.Semaphore;
public class SemaphoreExample {
public static void main(String[] args) {
Semaphore semaphore = new Semaphore(2); // সর্বাধিক ২টি পারমিট
Runnable task = () -> {
try {
System.out.println(Thread.currentThread().getName() + " is waiting for a permit...");
semaphore.acquire(); // পারমিট গ্রহণ
System.out.println(Thread.currentThread().getName() + " acquired a permit!");
// রিসোর্স ব্যবহার
Thread.sleep(2000);
System.out.println(Thread.currentThread().getName() + " released the permit.");
semaphore.release(); // পারমিট মুক্ত
} catch (InterruptedException e) {
e.printStackTrace();
}
};
// ৫টি থ্রেড চালু করা
for (int i = 0; i < 5; i++) {
new Thread(task).start();
}
}
}
আউটপুট:
- সর্বোচ্চ ২টি থ্রেড একসাথে কাজ করবে।
- বাকিরা পারমিটের জন্য অপেক্ষা করবে।
২. ডেটাবেস কানেকশন পুল ম্যানেজমেন্ট:
উদাহরণ: একটি ডেটাবেস কানেকশন পুলে সর্বাধিক ৩টি কানেকশন অ্যাক্সেস করা যাবে।
import java.util.concurrent.Semaphore;
class DatabaseConnection {
private static final Semaphore semaphore = new Semaphore(3); // সর্বাধিক ৩টি কানেকশন
public void accessDatabase() {
try {
semaphore.acquire();
System.out.println(Thread.currentThread().getName() + " connected to the database.");
// ডেটাবেসে কাজ করা
Thread.sleep(2000);
System.out.println(Thread.currentThread().getName() + " disconnected from the database.");
semaphore.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class DatabaseConnectionExample {
public static void main(String[] args) {
DatabaseConnection connection = new DatabaseConnection();
Runnable task = connection::accessDatabase;
for (int i = 0; i < 10; i++) {
new Thread(task).start();
}
}
}
৩. প্রযোজক-গ্রাহক সমস্যা (Producer-Consumer Problem):
উদাহরণ: একটি Buffer যেখানে সর্বাধিক ২টি আইটেম রাখা যাবে।
import java.util.concurrent.Semaphore;
import java.util.LinkedList;
import java.util.Queue;
class BoundedBuffer {
private final Queue<Integer> buffer = new LinkedList<>();
private final int capacity = 2;
private final Semaphore items = new Semaphore(0); // ভোগ করার জন্য আইটেমের সংখ্যা
private final Semaphore spaces = new Semaphore(capacity); // খালি জায়গার সংখ্যা
public void produce(int value) throws InterruptedException {
spaces.acquire(); // খালি জায়গা নিশ্চিত করা
synchronized (this) {
buffer.add(value);
System.out.println("Produced: " + value);
}
items.release(); // নতুন আইটেম যোগ করা
}
public int consume() throws InterruptedException {
items.acquire(); // ভোগ করার জন্য আইটেম নিশ্চিত করা
synchronized (this) {
int value = buffer.poll();
System.out.println("Consumed: " + value);
spaces.release(); // জায়গা মুক্ত করা
return value;
}
}
}
public class ProducerConsumerExample {
public static void main(String[] args) {
BoundedBuffer buffer = new BoundedBuffer();
Runnable producer = () -> {
for (int i = 0; i < 5; i++) {
try {
buffer.produce(i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
Runnable consumer = () -> {
for (int i = 0; i < 5; i++) {
try {
buffer.consume();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
new Thread(producer).start();
new Thread(consumer).start();
}
}
Semaphore এর পদ্ধতি
| মেথড | কাজ |
|---|---|
acquire() | একটি পারমিট গ্রহণ করে (অথবা ব্লক করে যদি পারমিট পাওয়া না যায়)। |
release() | একটি পারমিট মুক্ত করে। |
tryAcquire() | একটি পারমিট পাওয়ার চেষ্টা করে (ব্লক করে না)। |
availablePermits() | বর্তমানে অবশিষ্ট পারমিট সংখ্যা দেয়। |
Semaphore ব্যবহার করার সময় সতর্কতা
- ডেডলক এড়িয়ে চলুন:
acquire()কল করার পরrelease()নিশ্চিত করুন। - পারফরম্যান্স: সীমিত সংখ্যক পারমিট ব্যবহার করুন যাতে থ্রেডগুলি খুব বেশি সময় ধরে ব্লক না থাকে।
- সিঙ্ক্রোনাইজেশন: যদি একই রিসোর্স অ্যাক্সেস করা হয়,
synchronizedব্লক ব্যবহার করতে হতে পারে।
- Semaphore একটি কার্যকরী টুল যা থ্রেড সিঙ্ক্রোনাইজেশন এবং রিসোর্স ব্যবস্থাপনা সহজ করে।
- এটি বিশেষভাবে উপযোগী যেখানে নির্দিষ্ট সংখ্যক থ্রেডকে রিসোর্স অ্যাক্সেস করার অনুমতি দিতে হয় (যেমন কানেকশন পুল বা বাউন্ডেড বাফার)।
acquire()এবংrelease()মেথডগুলো সঠিকভাবে ব্যবহার করলে এটি ডেডলক এবং রিসোর্স ওভারলোড প্রতিরোধ করে।
Content added By
Read more