Semaphore হলো Java Concurrency API এর একটি অংশ যা java.util.concurrent প্যাকেজে অন্তর্ভুক্ত। এটি একটি সিঙ্ক্রোনাইজেশন টুল যা অ্যাক্সেস কন্ট্রোল মেকানিজম হিসেবে কাজ করে। Semaphore একটি নির্দিষ্ট সংখ্যক থ্রেডকে একত্রে একটি রিসোর্সে প্রবেশ করতে অনুমতি দেয়।
Semaphore কীভাবে কাজ করে?
- Permit Count:
- Semaphore এর একটি নির্দিষ্ট permit count থাকে, যা একটি থ্রেডকে রিসোর্সে অ্যাক্সেস করার অনুমতি দেয়।
- একটি থ্রেড যখন রিসোর্স ব্যবহার করে, তখন এটি একটি permit গ্রহণ করে। কাজ শেষ হলে permit মুক্ত করে।
- Blocking Behavior:
- যদি কোনো থ্রেড একটি permit পেতে ব্যর্থ হয় (কারণ সমস্ত permit ব্যস্ত), তবে সেটি ব্লক হয়ে অপেক্ষা করে যতক্ষণ না একটি permit পাওয়া যায়।
- Concurrency Management:
- Semaphore ব্যবহার করে নির্দিষ্ট সংখ্যক থ্রেড বা প্রক্রিয়াকে একত্রে একটি শেয়ারড রিসোর্সে কাজ করতে দেওয়া যায়।
Semaphore এর দুটি প্রধান ধরন:
- Counting Semaphore:
- একটি নির্দিষ্ট সংখ্যক permit নির্ধারণ করা হয়।
- উদাহরণ: রিসোর্সে ৫টি permit থাকলে, একবারে ৫টি থ্রেড রিসোর্সে অ্যাক্সেস করতে পারে।
- Binary Semaphore (Mutex):
- এটি মূলত একটি বিশেষ ধরনের Counting Semaphore, যেখানে permit সংখ্যা ১।
- উদাহরণ: একটি মিউটেক্স লক, যা একবারে শুধুমাত্র একটি থ্রেডকে অ্যাক্সেস করতে দেয়।
Semaphore এর প্রধান মেথডসমূহ:
| মেথড | বর্ণনা |
|---|---|
acquire() | একটি permit গ্রহণ করে। যদি permit না থাকে, থ্রেড ব্লক হয়ে অপেক্ষা করে। |
release() | permit মুক্ত করে, যা অন্য থ্রেড ব্যবহার করতে পারে। |
tryAcquire() | একটি permit পেতে চেষ্টা করে। সফল হলে true, ব্যর্থ হলে false রিটার্ন করে। |
availablePermits() | বর্তমানে কতটি permit অবশিষ্ট আছে তা জানায়। |
Semaphore এর উদাহরণ:
১. Counting Semaphore:
import java.util.concurrent.Semaphore;
public class SemaphoreExample {
public static void main(String[] args) {
Semaphore semaphore = new Semaphore(3); // 3 permits available
Runnable task = () -> {
try {
System.out.println(Thread.currentThread().getName() + " is trying to acquire permit...");
semaphore.acquire(); // Acquire a permit
System.out.println(Thread.currentThread().getName() + " acquired a permit.");
// Simulate some work
Thread.sleep(2000);
System.out.println(Thread.currentThread().getName() + " is releasing permit...");
semaphore.release(); // Release the permit
} catch (InterruptedException e) {
e.printStackTrace();
}
};
// Create and start multiple threads
for (int i = 1; i <= 5; i++) {
new Thread(task, "Thread-" + i).start();
}
}
}
আউটপুট (উদাহরণস্বরূপ):
Thread-1 is trying to acquire permit...
Thread-2 is trying to acquire permit...
Thread-3 is trying to acquire permit...
Thread-1 acquired a permit.
Thread-2 acquired a permit.
Thread-3 acquired a permit.
Thread-4 is trying to acquire permit...
Thread-5 is trying to acquire permit...
Thread-1 is releasing permit...
Thread-4 acquired a permit.
বর্ণনা:
- এখানে একটি
Semaphoreতৈরি করা হয়েছে যার ৩টি permit আছে। - একবারে ৩টি থ্রেড permit পেয়ে কাজ শুরু করে। অতিরিক্ত থ্রেড ব্লক হয়ে অপেক্ষা করে।
- কাজ শেষ হলে
release()কল করার মাধ্যমে permit মুক্ত করা হয়।
২. Binary Semaphore (Mutex):
import java.util.concurrent.Semaphore;
public class MutexExample {
public static void main(String[] args) {
Semaphore mutex = new Semaphore(1); // Only 1 permit, acting as a Mutex
Runnable criticalTask = () -> {
try {
System.out.println(Thread.currentThread().getName() + " is trying to acquire lock...");
mutex.acquire();
System.out.println(Thread.currentThread().getName() + " acquired lock.");
// Critical section
Thread.sleep(2000);
System.out.println(Thread.currentThread().getName() + " is releasing lock...");
mutex.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
};
// Create and start multiple threads
for (int i = 1; i <= 3; i++) {
new Thread(criticalTask, "Thread-" + i).start();
}
}
}
আউটপুট (উদাহরণস্বরূপ):
Thread-1 is trying to acquire lock...
Thread-1 acquired lock.
Thread-2 is trying to acquire lock...
Thread-3 is trying to acquire lock...
Thread-1 is releasing lock...
Thread-2 acquired lock.
বর্ণনা:
- এখানে একটি
Semaphoreব্যবহার করা হয়েছে মিউটেক্স লক হিসেবে। - একবারে শুধুমাত্র একটি থ্রেড রিসোর্স ব্যবহার করতে পারে। অন্য থ্রেডগুলো লক মুক্ত হওয়া পর্যন্ত অপেক্ষা করে।
Semaphore এর বাস্তব জীবনের প্রয়োগ:
- Database Connection Pooling:
- একবারে নির্দিষ্ট সংখ্যক ডেটাবেস কানেকশন ব্যবহারের অনুমতি।
- উদাহরণ: ১০টি কানেকশন পর্যন্ত ব্যবহার করা যায়, অতিরিক্ত থ্রেড অপেক্ষা করবে।
- Rate Limiting:
- নির্দিষ্ট সংখ্যক অনুরোধকে একত্রে প্রক্রিয়াকরণ।
- উদাহরণ: API কলের সীমাবদ্ধতা।
- Resource Management:
- থ্রেড-সেফ উপায়ে সীমিত রিসোর্স ব্যবহারের নিয়ন্ত্রণ।
- Thread Synchronization:
- থ্রেডের মধ্যে সিঙ্ক্রোনাইজেশন এবং ক্রিটিক্যাল সেকশন সুরক্ষিত রাখা।
Semaphore একটি শক্তিশালী সিঙ্ক্রোনাইজেশন টুল যা Java Concurrency API তে রিসোর্স শেয়ারিং এবং থ্রেড কন্ট্রোল পরিচালনার জন্য ব্যবহৃত হয়। এটি Counting এবং Binary Semaphore হিসেবে ব্যবহার করা যায়। Semaphore এর সঠিক ব্যবহার মাল্টিথ্রেডিং প্রোগ্রামে রিসোর্সের কার্যকর ব্যবস্থাপনা এবং ডেটা কনসিস্টেন্সি নিশ্চিত করতে সাহায্য করে।
Read more