মাল্টিথ্রেডিং ইমপ্লিমেন্ট করা হলে, একটি থ্রেড দ্বারা করা পরিবর্তন অন্য থ্রেডের কাছে দৃশ্যমান নাও হতে পারে। এটি ইঙ্গিত দেয় যে প্রতিটি থ্রেডের ভিউ একে অপরের সাপেক্ষে ইনকনসিস্টেন্ট। এটি মেমরি কনসিস্টেন্সি এরর নামে পরিচিত।
সিপিইউ মেইন মেমরি অ্যাক্সেস অন্য একটি ক্রমে শুরু করতে পারে,حينकि থ্রেডগুলো অন্য ক্রমে অ্যাক্সেস করতে পারে।
এটি সাধারণত রাইট অপারেশন পারফর্ম করার সময় সত্য, সিপিইউ ওয়েট টাইম এড়াতে।
রাইট অপারেশন একটি অ্যাটমিক অপারেশন, অর্থাৎ অন্য কোনো থ্রেড দ্বারা কোনো অপারেশন পারফর্ম করা হয় না যখন একটি রাইট অপারেশন চলছে।
এর পাশাপাশি, রাইট অপারেশন কোনো ক্রমে পারফর্ম হবে তা প্রতিটি অ্যাসোসিয়েটেড সিপিইউ জন্য কনসিস্টেন্টলি মেইন্টেইন করা হয়,حينकि সিপিইউগুলো অন্য সিপিইউ-এর রাইট টাইম ভিন্নভাবে বুঝতে পারে। এই ঘটনা মেমরি ইনকনসিস্টেন্সির দিকে নিয়ে যেতে পারে।
মেমরি ইনকনসিস্টেন্সি এরর কীভাবে এড়ানো যায়?
একটি happens-before রিলেশনশিপ প্রতিষ্ঠা করতে হবে যাতে মেমরি রাইট একটি একক থ্রেড দ্বারা পারফর্ম হয় এবং এটি একই মেমরিতে অন্য থ্রেড দ্বারা করা রিড অপারেশনের কাছে দৃশ্যমান হয়।
'start' ফাংশন এবং 'join' ফাংশন happens-before রিলেশনশিপ হিসেবে বিবেচিত হয়। 'start' ফাংশন নিশ্চিত করে যে নতুন তৈরি থ্রেড দৃশ্যমান। 'join' ফাংশন নিশ্চিত করে যে দৃশ্যমান থ্রেড অন্য থ্রেডের সাথে জয়েন হয়েছে।
উদাহরণ
import java.io.*; class class_shared{ static int m=2; void inc(){ for(int j=0;j<5;j++){ m = m+1; System.out.println("After its increment is "+m); } } void dec(){ for(int j=0;j<5;j++){ m = m-1; System.out.println("After its decrement is "+m); } } } public class Demo{ public static void main(String[] args){ final class_shared my_inst = new class_shared(); Thread my_t_1 = new Thread(){ @Override public void run(){ my_inst.inc(); } }; Thread my_t_2 = new Thread(){ @Override public void run(){ my_inst.dec(); } }; my_t_1.start(); my_t_2.start(); } }আউটপুট
After its increment is 3 After its decrement is 2 After its decrement is 2 After its decrement is 1 After its increment is 3 After its decrement is 0 After its increment is 1 After its increment is 1 After its decrement is 0 After its increment is 2
'class_shared' নামক একটি ক্লাস একটি স্ট্যাটিক মান এবং একটি void ফাংশন সংজ্ঞায়িত করে, যা সংখ্যাগুলোর ওপর ইটারেট করে এবং ইনক্রিমেন্ট করে কনসোলে দেখায়। 'dec' নামক আরেকটি ফাংশন সংখ্যাগুলোর ওপর ইটারেট করে এবং প্রতিবার ডিক্রিমেন্ট করে আউটপুট কনসোলে দেখায়। Demo নামক একটি ক্লাসে main ফাংশন থাকে যা ক্লাসের একটি ইনস্ট্যান্স তৈরি করে এবং একটি নতুন থ্রেড তৈরি করে। এই থ্রেডটি ওভাররাইড করা হয় এবং এই অবজেক্ট ইনস্ট্যান্সের ওপর run ফাংশন কল করা হয়। দ্বিতীয় থ্রেডের জন্যও একই কাজ করা হয়। এই দুটি থ্রেডকে 'start' ফাংশন দিয়ে কল করা হয়।