volatile কীওয়ার্ড জাভার কনকারেন্সি মডেলে একটি বিশেষ গুরুত্বপূর্ণ ভূমিকা পালন করে। এটি একটি ভ্যারিয়েবলকে থ্রেড-সেফ করার জন্য ব্যবহৃত হয়, যা নিশ্চিত করে যে একটি ভ্যারিয়েবলের আপডেট সব থ্রেডে দৃশ্যমান থাকবে।
volatile এর প্রধান বৈশিষ্ট্য
- মেমরি ভিজিবিলিটি (Memory Visibility):
- একটি
volatileভ্যারিয়েবলের মান যখন একটি থ্রেড পরিবর্তন করে, তখন তা অন্য থ্রেডের কাছে অবিলম্বে দৃশ্যমান হয়। - এটি মেমরি ব্যারিয়ার ব্যবহার করে ভ্যালু আপডেটকে মেমোরিতে সিঙ্ক্রোনাইজ করে।
- একটি
- ইনস্ট্রাকশন রিঅর্ডারিং প্রতিরোধ:
volatileনিশ্চিত করে যে কম্পাইলার বা প্রসেসর ইনস্ট্রাকশনগুলোর ক্রম পরিবর্তন করবে না।
volatile এর প্রয়োজনীয়তা
volatile ব্যবহার তখন গুরুত্বপূর্ণ যখন:
- একাধিক থ্রেড একটি ভ্যারিয়েবল অ্যাক্সেস করে এবং এটি আপডেট করার প্রয়োজন হয়।
- ডেটা কনসিস্টেন্সি নিশ্চিত করা জরুরি।
- লাইটওয়েট থ্রেড-সেফ ডেটা ম্যানেজমেন্ট প্রয়োজন, যেখানে লকিং প্রয়োজন হয় না।
volatile এর ব্যবহার
১. সাধারণ উদাহরণ: ফ্ল্যাগ ভ্যারিয়েবল
class VolatileExample {
private static volatile boolean running = true;
public static void main(String[] args) {
Thread thread = new Thread(() -> {
while (running) {
System.out.println("Thread is running...");
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Thread stopped.");
});
thread.start();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
running = false; // থ্রেড বন্ধ করার সিগন্যাল
System.out.println("Main thread set running to false.");
}
}
ব্যাখ্যা:
runningএকটিvolatileভ্যারিয়েবল। এটি নিশ্চিত করে যে যখন একটি থ্রেড মান পরিবর্তন করে, অন্য থ্রেড তৎক্ষণাৎ পরিবর্তনটি দেখতে পায়।
২. ইনস্ট্রাকশন রিঅর্ডারিং প্রতিরোধ
class VolatileReorderingExample {
private static volatile boolean flag = false;
private static int value = 0;
public static void main(String[] args) {
Thread writer = new Thread(() -> {
value = 42; // স্টেপ ১
flag = true; // স্টেপ ২
});
Thread reader = new Thread(() -> {
if (flag) {
System.out.println("Value: " + value); // সবসময় 42 হওয়া উচিত
}
});
writer.start();
reader.start();
}
}
ব্যাখ্যা:
volatile flagনিশ্চিত করে যেvalue = 42এর পরেflag = trueএক্সিকিউট হবে এবং ইনস্ট্রাকশন রিঅর্ডারিং এড়ানো হবে।
volatile এর সীমাবদ্ধতা
Atomicity নিশ্চিত করে না:
volatileকেবল মেমরি ভিজিবিলিটি নিশ্চিত করে। এটি অপারেশনগুলোকে পরমাণুকরণ (atomic) করে না।- যেমন,
count++একটিvolatileভ্যারিয়েবলে থ্রেড-সেফ নয়।
সমাধান:
AtomicIntegerবাsynchronizedব্যবহার করতে হবে।- লকিং এড়ানো যায় না:
- যখন জটিল ডেটা স্ট্রাকচারের জন্য থ্রেড-সেফটি প্রয়োজন, তখন লকিং ব্যবহার করতে হতে পারে।
Atomicity সমস্যা উদাহরণ
class NonAtomicVolatileExample {
private static volatile int counter = 0;
public static void main(String[] args) {
Thread incrementer1 = new Thread(() -> {
for (int i = 0; i < 1000; i++) {
counter++; // Not thread-safe
}
});
Thread incrementer2 = new Thread(() -> {
for (int i = 0; i < 1000; i++) {
counter++; // Not thread-safe
}
});
incrementer1.start();
incrementer2.start();
try {
incrementer1.join();
incrementer2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Final Counter Value: " + counter); // ফলাফল অপ্রত্যাশিত হতে পারে
}
}
সমাধান: AtomicInteger ব্যবহার করুন।
import java.util.concurrent.atomic.AtomicInteger;
class AtomicExample {
private static AtomicInteger counter = new AtomicInteger(0);
public static void main(String[] args) {
Thread incrementer1 = new Thread(() -> {
for (int i = 0; i < 1000; i++) {
counter.incrementAndGet();
}
});
Thread incrementer2 = new Thread(() -> {
for (int i = 0; i < 1000; i++) {
counter.incrementAndGet();
}
});
incrementer1.start();
incrementer2.start();
try {
incrementer1.join();
incrementer2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Final Counter Value: " + counter.get()); // ফলাফল সঠিক
}
}
কখন volatile ব্যবহার করবেন?
- একটি ফ্ল্যাগ ভ্যারিয়েবল থ্রেডের মধ্যে সিগন্যাল পাস করার জন্য।
- যখন একাধিক থ্রেড একটি ভ্যারিয়েবল পড়ে এবং সেট করে, এবং ডেটা রেস অবস্থার সম্ভাবনা নেই।
- রিড-হেভি অপারেশন এবং লাইটওয়েট থ্রেড সিঙ্ক্রোনাইজেশনের জন্য।
volatileএকটি লাইটওয়েট মেকানিজম যা মেমরি ভিজিবিলিটি নিশ্চিত করে।- এটি রিড এবং রাইট অপারেশনের মধ্যে ইনস্ট্রাকশন রিঅর্ডারিং প্রতিরোধ করে।
- যদিও এটি থ্রেড-সেফটি নিশ্চিত করে, এটি পরমাণুকরণ (atomicity) নিশ্চিত করে না। জটিল পরিস্থিতিতে
synchronizedবাAtomicক্লাস ব্যবহার করা উচিত।
Content added By
Read more