JavaRush /جاوا بلاگ /Random-UR /تھریڈ سنکرونائزیشن۔ جاوا میں مطابقت پذیر آپریٹر

تھریڈ سنکرونائزیشن۔ جاوا میں مطابقت پذیر آپریٹر

گروپ میں شائع ہوا۔
ہیلو! آج ہم ملٹی تھریڈ پروگرامنگ کی خصوصیات پر غور کرتے رہیں گے اور تھریڈ سنکرونائزیشن کے بارے میں بات کریں گے۔
تھریڈ سنکرونائزیشن۔  آپریٹر مطابقت پذیر - 1
"ہم وقت سازی" کیا ہے؟ پروگرامنگ کے دائرے سے باہر، اس سے مراد کسی قسم کا سیٹ اپ ہے جو دو آلات یا پروگراموں کو ایک ساتھ کام کرنے کی اجازت دیتا ہے۔ مثال کے طور پر، ایک سمارٹ فون اور کمپیوٹر کو گوگل اکاؤنٹ کے ساتھ ہم آہنگ کیا جا سکتا ہے، اور ویب سائٹ پر موجود ذاتی اکاؤنٹ کو سوشل نیٹ ورکس کے اکاؤنٹس کے ساتھ ہم آہنگ کیا جا سکتا ہے تاکہ ان کا استعمال کرتے ہوئے لاگ ان کیا جا سکے۔ تھریڈ سنکرونائزیشن کا ایک ہی مطلب ہے: یہ ترتیب دے رہا ہے کہ تھریڈز ایک دوسرے کے ساتھ کیسے تعامل کرتے ہیں۔ پچھلے لیکچرز میں ہمارے تھریڈز ایک دوسرے سے الگ رہتے اور کام کرتے تھے۔ ایک کچھ گن رہا تھا، دوسرا سو رہا تھا، تیسرا کنسول پر کچھ دکھا رہا تھا، لیکن وہ ایک دوسرے سے بات نہیں کر رہے تھے۔ حقیقی پروگراموں میں ایسے حالات بہت کم ہوتے ہیں۔ کئی تھریڈز فعال طور پر کام کر سکتے ہیں، مثال کے طور پر، ڈیٹا کے ایک ہی سیٹ کے ساتھ اور اس میں کچھ تبدیل کر سکتے ہیں۔ اس سے مسائل پیدا ہوتے ہیں۔ تصور کریں کہ متعدد تھریڈز ایک ہی جگہ پر متن لکھ رہے ہیں، جیسے کہ ٹیکسٹ فائل یا کنسول۔ اس معاملے میں یہ فائل یا کنسول ایک مشترکہ وسیلہ بن جاتا ہے۔ تھریڈز ایک دوسرے کے وجود کے بارے میں نہیں جانتے ہیں، لہذا وہ صرف اس وقت میں ہر وہ چیز لکھ دیتے ہیں جو وہ کر سکتے ہیں جب تھریڈ شیڈیولر ان کے لیے مختص کرتا ہے۔ کورس کے ایک حالیہ لیکچر میں، ہمارے پاس اس کی ایک مثال تھی کہ اس سے کیا نتیجہ نکلے گا، آئیے اسے یاد رکھیں: تھریڈ سنکرونائزیشن۔  مطابقت پذیر آپریٹر - 2اس کی وجہ یہ ہے کہ تھریڈز ایک دوسرے کے ساتھ کام کو مربوط کیے بغیر مشترکہ وسائل، کنسول کے ساتھ کام کرتے ہیں۔ اگر تھریڈ شیڈیولر نے Thread-1 کے لیے وقت مختص کیا ہے، تو یہ فوری طور پر کنسول پر سب کچھ لکھ دیتا ہے۔ کیا دوسرے تھریڈز پہلے ہی لکھنے میں کامیاب ہو چکے ہیں یا لکھنے میں کامیاب نہیں ہوئے یہ اہم نہیں ہے۔ نتیجہ، جیسا کہ آپ دیکھ سکتے ہیں، تباہ کن ہے۔ لہذا، ملٹی تھریڈڈ پروگرامنگ میں، ایک خاص تصور mutex متعارف کرایا گیا تھا (انگریزی سے "mutex"، "باہمی اخراج" - "باہمی اخراج") ۔ ایک mutex کا مقصد ایک میکانزم فراہم کرنا ہے تاکہ ایک مخصوص وقت میں صرف ایک دھاگے کو کسی چیز تک رسائی حاصل ہو۔ اگر Thread-1 نے آبجیکٹ A کا mutex حاصل کر لیا ہے، تو دوسرے تھریڈز کو اس میں کچھ بھی تبدیل کرنے کے لیے اس تک رسائی حاصل نہیں ہوگی۔ جب تک آبجیکٹ A کا mutex جاری نہیں ہوتا، باقی دھاگوں کو انتظار کرنے پر مجبور کیا جائے گا۔ حقیقی زندگی کی مثال: تصور کریں کہ آپ اور 10 دیگر اجنبی تربیت میں حصہ لے رہے ہیں۔ آپ کو خیالات کا اظہار کرنے اور کسی چیز پر تبادلہ خیال کرنے کی ضرورت ہے۔ لیکن، چونکہ آپ پہلی بار ایک دوسرے کو دیکھ رہے ہیں، تاکہ ایک دوسرے کو مستقل طور پر روکا نہ جائے اور آپس میں گڑبڑ نہ کریں، آپ "ٹاکنگ بال" کے اصول کا استعمال کرتے ہیں: صرف ایک شخص بول سکتا ہے - جس کے پاس گیند ہے اسکے ہاتھ. اس طرح بحث کافی اور نتیجہ خیز ثابت ہوتی ہے۔ لہذا، ایک mutex، جوہر میں، ایک ایسی گیند ہے. اگر کسی شے کا mutex ایک دھاگے کے ہاتھ میں ہے، تو دوسرے دھاگے آبجیکٹ تک رسائی حاصل نہیں کر سکیں گے۔ mutex بنانے کے لیے آپ کو کچھ کرنے کی ضرورت نہیں ہے: یہ پہلے سے ہی کلاس میں بنا ہوا ہے Object، جس کا مطلب ہے کہ جاوا میں موجود ہر شے کے پاس ہے۔

جاوا میں مطابقت پذیر آپریٹر کیسے کام کرتا ہے۔

آئیے ایک نئے کلیدی لفظ سے واقف ہوں - مطابقت پذیر ۔ یہ ہمارے کوڈ کے ایک مخصوص ٹکڑے کو نشان زد کرتا ہے۔ اگر کوڈ کے ایک بلاک کو مطابقت پذیر مطلوبہ الفاظ کے ساتھ نشان زد کیا گیا ہے، تو اس کا مطلب ہے کہ بلاک کو ایک وقت میں صرف ایک تھریڈ کے ذریعے عمل میں لایا جا سکتا ہے۔ ہم وقت سازی کو مختلف طریقوں سے لاگو کیا جا سکتا ہے۔ مثال کے طور پر، ایک مکمل مطابقت پذیر طریقہ بنائیں:
public synchronized void doSomething() {

   //...method logic
}
یا کوڈ کا ایک بلاک لکھیں جہاں کسی چیز پر مطابقت پذیری کی جاتی ہے:
public class Main {

   private Object obj = new Object();

   public void doSomething() {

       //...some logic available to all threads

       synchronized (obj) {

           //logic that is only available to one thread at a time
       }
   }
}
مطلب سادہ ہے۔ اگر ایک تھریڈ کوڈ کے کسی ایسے بلاک میں داخل ہوتا ہے جس پر لفظ مطابقت پذیری کے ساتھ نشان زد ہوتا ہے، تو یہ فوری طور پر آبجیکٹ کا mutex حاصل کر لیتا ہے، اور دوسرے تمام تھریڈز جو اسی بلاک یا طریقہ میں داخل ہونے کی کوشش کرتے ہیں، اس وقت تک انتظار کرنے پر مجبور ہوتے ہیں جب تک کہ پچھلا تھریڈ اپنا کام مکمل نہ کر لے اور اسے جاری کرے۔ مانیٹر تھریڈ سنکرونائزیشن۔  مطابقت پذیر آپریٹر - 3ویسے! کورس کے لیکچرز میں آپ نے مطابقت پذیری کی مثالیں پہلے ہی دیکھی ہیں، لیکن وہ مختلف نظر آئیں:
public void swap()
{
   synchronized (this)
   {
       //...method logic
   }
}
موضوع آپ کے لیے نیا ہے، اور یقیناً پہلے نحو میں الجھن ہوگی۔ اس لیے فوراً یاد رکھیں تاکہ بعد میں لکھنے کے طریقوں میں الجھن نہ ہو۔ لکھنے کے ان دو طریقوں کا مطلب ایک ہی ہے:
public void swap() {

   synchronized (this)
   {
       //...method logic
   }
}


public synchronized void swap() {

   }
}
پہلی صورت میں، آپ طریقہ داخل کرنے کے فوراً بعد کوڈ کا ایک مطابقت پذیر بلاک بناتے ہیں۔ یہ آبجیکٹ کے ذریعہ مطابقت پذیر ہے this، یعنی موجودہ آبجیکٹ کے ذریعہ۔ اور دوسری مثال میں آپ نے لفظ کو پورے طریقہ پر سنکرونائز کیا ہے۔ اب کسی بھی چیز کو واضح طور پر بتانے کی ضرورت نہیں ہے جس پر ہم آہنگی کی جاتی ہے۔ ایک بار جب ایک پورا طریقہ ایک لفظ کے ساتھ نشان زد ہو جائے تو، یہ طریقہ خود بخود کلاس کی تمام اشیاء کے لیے مطابقت پذیر ہو جائے گا۔ آئیے اس بحث میں نہیں پڑتے کہ کون سا طریقہ بہتر ہے۔ ابھی کے لیے، آپ کو جو سب سے زیادہ پسند ہے اس کا انتخاب کریں :) اہم بات یہ ہے کہ یاد رکھیں: آپ مطابقت پذیر طریقہ کا اعلان صرف اس صورت میں کر سکتے ہیں جب اس کے اندر موجود تمام منطق ایک ہی وقت میں ایک تھریڈ کے ذریعے عمل میں لائی جائیں۔ مثال کے طور پر، اس صورت میں doSomething()طریقہ کار کو مطابقت پذیر بنانے میں غلطی ہوگی:
public class Main {

   private Object obj = new Object();

   public void doSomething() {

       //...some logic available to all threads

       synchronized (obj) {

           //logic that is only available to one thread at a time
       }
   }
}
جیسا کہ آپ دیکھ سکتے ہیں، طریقہ کا ایک حصہ منطق پر مشتمل ہے جس کے لیے مطابقت پذیری کی ضرورت نہیں ہے۔ اس میں موجود کوڈ کو بیک وقت کئی تھریڈز کے ذریعے عمل میں لایا جا سکتا ہے، اور تمام اہم جگہوں کو ایک الگ سنکرونائزڈ بلاک کے لیے مختص کیا جاتا ہے۔ اور ایک لمحہ۔ آئیے ناموں کے تبادلے کے ساتھ لیکچر سے اپنی مثال پر خوردبین کے نیچے دیکھیں:
public void swap()
{
   synchronized (this)
   {
       //...method logic
   }
}
براہ کرم نوٹ کریں: ہم آہنگی کا استعمال کرتے ہوئے کیا جاتا ہے this۔ یعنی کسی خاص چیز کے لیے MyClass۔ تصور کریں کہ ہمارے پاس 2 دھاگے ہیں ( Thread-1اور Thread-2) اور صرف ایک چیز MyClass myClass۔ اس صورت میں، اگر Thread-1طریقہ کو کہا جاتا ہے تو myClass.swap()، آبجیکٹ کا mutex مصروف ہو جائے گا، اور Thread-2جب آپ اسے کال کرنے کی کوشش کریں گے، تو myClass.swap()یہ mutex کے آزاد ہونے کے انتظار میں لٹکا رہے گا۔ اگر ہمارے پاس 2 تھریڈز اور 2 آبجیکٹ ہیں MyClass- myClass1اور myClass2- مختلف اشیاء پر، تو ہمارے تھریڈز آسانی سے بیک وقت مطابقت پذیر طریقوں کو انجام دے سکتے ہیں۔ پہلا تھریڈ یہ کرتا ہے:
myClass1.swap();
دوسرا کرتا ہے:
myClass2.swap();
اس صورت میں، طریقہ کے اندر مطابقت پذیر کلیدی لفظ swap()پروگرام کے عمل کو متاثر نہیں کرے گا، کیونکہ مطابقت پذیری ایک مخصوص چیز پر کی جاتی ہے۔ اور مؤخر الذکر صورت میں، ہمارے پاس 2 اشیاء ہیں، لہذا، دھاگے ایک دوسرے کے لیے مسائل پیدا نہیں کرتے ہیں۔ سب کے بعد، دو اشیاء میں 2 مختلف mutexes ہیں، اور ان کی گرفتاری ایک دوسرے پر منحصر نہیں ہے.

جامد طریقوں میں مطابقت پذیری کی خصوصیات

لیکن کیا ہوگا اگر آپ کو جامد طریقہ کو ہم آہنگ کرنے کی ضرورت ہو؟
class MyClass {
   private static String name1 = "Olya";
   private static String name2 = "Lena";

   public static synchronized void swap() {
       String s = name1;
       name1 = name2;
       name2 = s;
   }

}
یہ واضح نہیں ہے کہ اس معاملے میں میوٹیکس کے طور پر کیا کام کرے گا۔ سب کے بعد، ہم نے پہلے ہی فیصلہ کیا ہے کہ ہر چیز کو ایک mutex ہے. لیکن مسئلہ یہ ہے کہ جامد طریقہ کو کہنے کے لیے MyClass.swap()ہمیں اشیاء کی ضرورت نہیں ہے: طریقہ جامد ہے! تو، آگے کیا ہے؟ :/ اصل میں، اس کے ساتھ کوئی مسئلہ نہیں ہے. جاوا کے تخلیق کاروں نے ہر چیز کا خیال رکھا :) اگر اہم "ملٹی تھریڈڈ" منطق پر مشتمل طریقہ جامد ہے، تو ہم آہنگی کلاس کے لحاظ سے کی جائے گی۔ زیادہ وضاحت کے لیے، مندرجہ بالا کوڈ کو اس طرح دوبارہ لکھا جا سکتا ہے:
class MyClass {
   private static String name1 = "Olya";
   private static String name2 = "Lena";

   public static void swap() {

       synchronized (MyClass.class) {
           String s = name1;
           name1 = name2;
           name2 = s;
       }
   }

}
اصولی طور پر، آپ خود ہی اس کے بارے میں سوچ سکتے تھے: چونکہ وہاں کوئی اشیاء نہیں ہیں، اس لیے ہم آہنگی کا طریقہ کار کسی نہ کسی طرح خود ہی کلاسوں میں "مشکل" ہونا چاہیے۔ یہ اس طرح ہے: آپ کلاسوں میں بھی ہم آہنگی پیدا کر سکتے ہیں۔
تبصرے
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION