জাভা ইন্টার-থ্রেড কমিউনিকেশনের জন্য wait(), notify(), এবং notifyAll() মেথড সরবরাহ করে যা Object ক্লাসের অংশ। এই মেথডগুলো থ্রেডগুলোকে একে অপরের সাথে যোগাযোগ করতে সাহায্য করে, বিশেষ করে যখন তারা শেয়ারড রিসোর্সের সাথে কাজ করছে। নিচে একটি উদাহরণ দেওয়া হল, যেখানে দুটি থ্রেড (প্রোডিউসার এবং কনজিউমার) একটি আইটেম উৎপাদন এবং ভক্ষণ করছে এবং তাদের মধ্যে যোগাযোগ হচ্ছে wait() এবং notify() মেথড ব্যবহার করে।
উদাহরণ: প্রোডিউসার-কনজিউমার সমস্যা
ব্যাখ্যা:
wait()মেথড থ্রেডটিকে লক মুক্ত করে দেয় এবং ওয়েটিং স্টেটে পাঠিয়ে দেয়।notify()মেথড একটি থ্রেডকে জাগিয়ে তোলে যে থ্রেডটি ওয়েটিং স্টেটে ছিল।notifyAll()মেথড সব ওয়েটিং থ্রেডকে জাগিয়ে তোলে।
নিচে একটি প্রোডিউসার-কনজিউমার পরিস্থিতির উদাহরণ দেওয়া হল:
class SharedResource {
private int item = 0;
// এই মেথডটি প্রোডিউসার থ্রেড দ্বারা আইটেম উৎপাদনের জন্য কল করা হয়
public synchronized void produce() throws InterruptedException {
while (item != 0) {
wait(); // আইটেম কনজিউম হওয়ার জন্য অপেক্ষা করে
}
item++;
System.out.println("Produced item: " + item);
notify(); // কনজিউমারকে জানান যে একটি আইটেম উৎপাদিত হয়েছে
}
// এই মেথডটি কনজিউমার থ্রেড দ্বারা আইটেম ভক্ষণ করার জন্য কল করা হয়
public synchronized void consume() throws InterruptedException {
while (item == 0) {
wait(); // আইটেম না থাকার জন্য অপেক্ষা করে
}
System.out.println("Consumed item: " + item);
item--;
notify(); // প্রোডিউসারকে জানান যে আইটেম ভক্ষণ করা হয়েছে
}
}
class Producer implements Runnable {
SharedResource resource;
public Producer(SharedResource resource) {
this.resource = resource;
}
@Override
public void run() {
try {
while (true) {
resource.produce();
Thread.sleep(1000); // 1 সেকেন্ড ঘুমায় যাতে উৎপাদনের সময় সিমুলেট করা যায়
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class Consumer implements Runnable {
SharedResource resource;
public Consumer(SharedResource resource) {
this.resource = resource;
}
@Override
public void run() {
try {
while (true) {
resource.consume();
Thread.sleep(1500); // 1.5 সেকেন্ড ঘুমায় যাতে ভক্ষণ সময় সিমুলেট করা যায়
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class InterThreadCommunicationExample {
public static void main(String[] args) {
SharedResource resource = new SharedResource();
Thread producerThread = new Thread(new Producer(resource));
Thread consumerThread = new Thread(new Consumer(resource));
producerThread.start();
consumerThread.start();
}
}
কোডের ব্যাখ্যা:
- SharedResource ক্লাস:
- এই ক্লাসটি শেয়ারড রিসোর্স (আইটেম) প্রতিনিধিত্ব করে।
- এর দুটি মেথড রয়েছে:
produce()এবংconsume(), যেগুলো সিঙ্ক্রোনাইজড যাতে একসময় কেবল একটি থ্রেড রিসোর্সটি অ্যাক্সেস করতে পারে। produce()মেথডটি অপেক্ষা করবে যদি আইটেমটি কনজিউম না হয় (অর্থাৎ,item != 0), আরconsume()মেথডটি অপেক্ষা করবে যদি কোনো আইটেম না থাকে কনজিউম করার জন্য (অর্থাৎ,item == 0)।- একটি আইটেম উৎপাদন করার পরে,
produce()মেথডnotify()কল করে কনজিউমার থ্রেডকে জাগিয়ে তোলে। - একটি আইটেম কনজিউম করার পরে,
consume()মেথডnotify()কল করে প্রোডিউসার থ্রেডকে জাগিয়ে তোলে।
- Producer এবং Consumer ক্লাস:
ProducerএবংConsumerক্লাস দুটিRunnableইন্টারফেস ইমপ্লিমেন্ট করে এবং তাদেরrun()মেথডে অবিরাম আইটেম উৎপাদন এবং কনজিউম করার কাজ করে।Producer1 সেকেন্ডের জন্য ঘুমায় আইটেম উৎপাদনের পর, এবংConsumer1.5 সেকেন্ডের জন্য ঘুমায় আইটেম কনজিউম করার পর, যাতে উৎপাদন এবং ভক্ষণ সময় সিমুলেট করা যায়।
- Main ক্লাস:
main()মেথডে,ProducerএবংConsumerক্লাসের ইনস্ট্যান্স তৈরি করা হয় এবং তাদের থ্রেড চালু করা হয়।- থ্রেডগুলো অবিরাম চলতে থাকে, আইটেম উৎপাদন এবং কনজিউম করে।
মূল ধারণাসমূহ:
synchronized: এটি নিশ্চিত করে যে একসময় একটিমাত্র থ্রেডproduce()এবংconsume()মেথড অ্যাক্সেস করতে পারে, যা রেস কন্ডিশন (race condition) প্রতিরোধ করে।wait(): এটি থ্রেডটিকে অপেক্ষায় রাখে যতক্ষণ না অন্য থ্রেড তাকে জাগিয়ে তুলে।notify(): এটি একটি থ্রেডকে জাগিয়ে তোলে যেটি ওয়েটিং অবস্থায় ছিল।notifyAll(): এটি সব ওয়েটিং থ্রেডকে জাগিয়ে তোলে। (এই উদাহরণেnotifyAll()ব্যবহার করা হয়নি, তবে এটি যখন একাধিক থ্রেড থাকে তখন প্রয়োজন হতে পারে।)
এই উদাহরণটি দেখায় কিভাবে ইন্টার-থ্রেড কমিউনিকেশন ব্যবহার করে থ্রেডগুলো একে অপরের সাথে যোগাযোগ করতে পারে এবং সিঙ্ক্রোনাইজডভাবে শেয়ারড রিসোর্সের সাথে কাজ করতে পারে।
Read more