জাভা কনকারেন্সি হল একটি প্রোগ্রামিং মডেল যা মাল্টি-থ্রেডিং এনভায়রনমেন্টে কার্যক্রম পরিচালনা করতে ব্যবহৃত হয়। Java Memory Model (JMM) হলো জাভার মাল্টি-থ্রেডেড অ্যাপ্লিকেশনে মেমরি অ্যাক্সেসের জন্য একটি ফ্রেমওয়ার্ক যা ডেটার সঠিকতা এবং কনসিসটেন্সি নিশ্চিত করে।
Java Memory Model (JMM) কি?
JMM জাভার ভাষা স্পেসিফিকেশনের অংশ, যা নির্ধারণ করে:
- কিভাবে ভেরিয়েবলগুলি থ্রেডের মধ্যে শেয়ার করা হয়।
- মেমরি অ্যাক্সেস করার সময় থ্রেডগুলোর মধ্যে কি অর্ডার ফলো করা হবে।
JMM নিশ্চিত করে যে একাধিক থ্রেড একসঙ্গে কাজ করার সময় সঠিক এবং অনুমানযোগ্য আচরণ বজায় থাকবে।
JMM এর ভূমিকা
- ভেরিয়েবল শেয়ারিং নিয়ন্ত্রণ (Variable Sharing Control):
- JMM নির্ধারণ করে থ্রেডগুলো কীভাবে ভেরিয়েবল অ্যাক্সেস এবং আপডেট করবে।
- ভলাটাইল (volatile) ভেরিয়েবল ব্যবহার করে থ্রেড-সেফ শেয়ারিং নিশ্চিত করা যায়।
- থ্রেড কমিউনিকেশন (Thread Communication):
- JMM নিশ্চিত করে যে একটি থ্রেড যা লিখেছে, অন্য একটি থ্রেড তা পড়তে সক্ষম হবে।
- সিঙ্ক্রোনাইজেশন (Synchronization) ব্যবহারের মাধ্যমে এটি সহজতর করা হয়।
- মেমরি ভিজিবিলিটি (Memory Visibility):
- একাধিক থ্রেড যখন একই ডেটা ব্যবহার করে, তখন JMM নিশ্চিত করে যে থ্রেডগুলি সর্বশেষ মান দেখতে পাবে।
- ভলাটাইল এবং সিঙ্ক্রোনাইজড ব্লক ব্যবহার করে ভিজিবিলিটি নিশ্চিত করা হয়।
- ইনস্ট্রাকশন রিঅর্ডারিং নিয়ন্ত্রণ (Instruction Reordering Control):
- JMM থ্রেডের নির্বাহের সময় CPU এবং কম্পাইলার অপ্টিমাইজেশনের কারণে ইনস্ট্রাকশন রিঅর্ডারিং প্রতিরোধ করে।
- সঠিক আউটপুট নিশ্চিত করতে হ্যাপেন্স-বিফোর (Happens-Before) সম্পর্ক ব্যবহার করা হয়।
- ডেডলক এবং রেস কন্ডিশন প্রতিরোধ (Deadlock and Race Condition Prevention):
- JMM থ্রেডগুলোর মধ্যে ডাটা অ্যাক্সেসের সঠিক ক্রম বজায় রেখে ডেডলক এবং রেস কন্ডিশন এড়াতে সাহায্য করে।
JMM এর গুরুত্বপূর্ণ উপাদানসমূহ
১. Volatile Keyword
- ভলাটাইল ভেরিয়েবলগুলো JMM-কে নির্দেশ করে যে এটি মেইন মেমরি থেকে সরাসরি পড়া এবং লেখা হবে।
- এটি মেমরি ভিজিবিলিটি নিশ্চিত করে।
class VolatileExample {
private volatile boolean running = true;
public void stopRunning() {
running = false; // এই মানটি অন্য থ্রেডে দৃশ্যমান হবে
}
}
২. Happens-Before Relationship
- JMM থ্রেডগুলোর মধ্যে কোন অপারেশন আগে ঘটেছে এবং কোনটি পরে ঘটেছে তা নির্ধারণ করে।
- উদাহরণ:
- একটি লক release করার আগে সমস্ত আপডেট দৃশ্যমান হয়।
- একটি থ্রেড যা লক acquire করে, এটি সর্বশেষ পরিবর্তন দেখতে পায়।
৩. Synchronization
- JMM নিশ্চিত করে যে সিঙ্ক্রোনাইজড ব্লক ব্যবহারের মাধ্যমে ডেটার অ্যাক্সেস থ্রেড-সেফ।
class SynchronizedExample {
private int count = 0;
public synchronized void increment() {
count++;
}
public synchronized int getCount() {
return count;
}
}
৪. Final Fields
- JMM ফাইনাল ভেরিয়েবলগুলোর ইমিউটেবল কনস্ট্রাকশন নিশ্চিত করে।
- কন্সট্রাকটরের সময় যদি ফাইনাল ফিল্ড ইনিশিয়ালাইজ করা হয়, তবে এটি নিরাপদে শেয়ার করা যায়।
class FinalFieldExample {
private final int value;
public FinalFieldExample(int value) {
this.value = value;
}
public int getValue() {
return value;
}
}
JMM এর ব্যবহার ও চ্যালেঞ্জ
ব্যবহার:
- মাল্টি-থ্রেডেড অ্যাপ্লিকেশন তৈরি করা।
- ডাটা কনসিসটেন্সি এবং ভিজিবিলিটি নিশ্চিত করা।
- ইনস্ট্রাকশন রিঅর্ডারিং প্রতিরোধ করা।
চ্যালেঞ্জ:
- ডেডলক, রেস কন্ডিশন, এবং লাইভলক সমস্যা।
- জটিল থ্রেড সিঙ্ক্রোনাইজেশন ম্যানেজ করা।
- সঠিকভাবে ভলাটাইল এবং সিঙ্ক্রোনাইজড ব্যবহারের কৌশল জানা।
উদাহরণ প্রোগ্রাম: Happens-Before রিলেশন
class HappensBeforeExample {
private int count = 0;
private boolean flag = false;
public synchronized void writer() {
count = 42; // Write to count
flag = true; // Write to flag
}
public synchronized void reader() {
if (flag) { // Read flag
System.out.println("Count: " + count); // Read count
}
}
public static void main(String[] args) {
HappensBeforeExample example = new HappensBeforeExample();
Thread writerThread = new Thread(example::writer);
Thread readerThread = new Thread(example::reader);
writerThread.start();
readerThread.start();
}
}
JMM এর মাধ্যমে জাভার মাল্টি-থ্রেডিং কার্যক্রম সঠিকভাবে পরিচালিত হয়। এটি:
- মেমরি ভিজিবিলিটি নিশ্চিত করে।
- থ্রেড সিঙ্ক্রোনাইজেশন সহজ করে।
- ডেটা সঠিকতা বজায় রাখে।
JMM-কে ভালোভাবে বুঝে সঠিকভাবে ব্যবহার করলে জাভা অ্যাপ্লিকেশনের কনকারেন্সি সমস্যা সহজে সমাধান করা যায়।
Read more