JavaRush /جاوا بلاگ /Random-UR /جاوا میں SynchronousQueue مثال - مسئلہ حل کرنا Producer C...
profeg
سطح

جاوا میں SynchronousQueue مثال - مسئلہ حل کرنا Producer Consumer

گروپ میں شائع ہوا۔
جاوا میں SynchronousQueue مثال - مسئلہ حل کرنا Producer Consumer
SynchronousQueue ایک خاص قسم کی BlockingQueue ہے جس میں ہر داخل آپریشن کو دوسرے تھریڈ میں متعلقہ ہٹانے کی کمانڈ کا انتظار کرنا چاہیے، اور اس کے برعکس۔ جب آپ SynchronousQueue پر put() طریقہ کو کال کرتے ہیں، تو یہ اس وقت تک بلاک ہوجاتا ہے جب تک کہ کوئی دوسرا تھریڈ اس عنصر سے اس عنصر کو نہ لے لے۔ اس کے مطابق، اگر کوئی دوسرا تھریڈ اس میں سے کسی عنصر کو ہٹانے کی کوشش کرتا ہے، اور عنصر وہاں نہیں ہے، تو وہ تھریڈ اس وقت تک بلاک ہو جاتا ہے جب تک کہ دوسرا تھریڈ عنصر کو قطار میں نہ ڈال دے۔ آپ SynchronousQueue کے بارے میں سوچ سکتے ہیں کہ ایک ایتھلیٹ ( دھاگہ ) اولمپک ٹارچ کے ساتھ دوڑ رہا ہے، وہ ٹارچ کے ساتھ دوڑتا ہے (جس چیز کو آگے بڑھایا جا رہا ہے) اور اسے دوسری طرف انتظار کر رہے دوسرے ایتھلیٹ تک پہنچاتا ہے۔ اگر آپ نام پر دھیان دیتے ہیں، تو آپ سمجھ جائیں گے کہ SynchronousQueue کا نام ایک وجہ سے رکھا گیا ہے؛ یہ ڈیٹا کو ہم آہنگی سے دوسرے تھریڈ میں منتقل کرتا ہے ۔ یہ انتظار کرتا ہے کہ کوئی ڈیٹا اٹھانے کے بجائے اسے ڈالے اور باہر نکلے (ایک غیر مطابقت پذیر آپریشن)۔ اگر آپ CSP اور Ada سے واقف ہیں، تو آپ جانتے ہیں کہ مطابقت پذیر قطاریں دھاگوں کی میٹنگ کی طرح ہوتی ہیں۔ وہ کنٹرول ٹرانسفر کنسٹرکٹس کے لیے موزوں ہیں جس میں ایک دھاگے میں چلنے والی چیز کو کسی دوسرے دھاگے میں کسی چیز کے ساتھ مطابقت پذیر ہونا چاہیے تاکہ کچھ معلومات، واقعہ یا کام اس تک پہنچایا جا سکے۔ پچھلے ملٹی تھریڈڈ پروگرامنگ ٹیوٹوریلز میں، ہم نے سیکھا کہ کس طرح انتظار اور اطلاع اور بلاکنگ کیو طریقوں کا استعمال کرتے ہوئے پروڈیوسر صارفین کے مسئلے کو حل کرنا ہے ۔ اب ہم سیکھیں گے کہ SynchronousQueue کا استعمال کرتے ہوئے پروڈیوسر-صارف پیٹرن کو کیسے لاگو کیا جائے۔ یہ کلاس پروڈیوسر اور صارفین کے دھاگوں کے انتظار کے آرڈر کے لیے منصفانہ رویے کی بھی حمایت کرتی ہے۔ پہلے سے طے شدہ طور پر، اس آرڈر کی ضمانت نہیں ہے۔ تاہم، منصفانہ خصوصیات کے ساتھ بنائی گئی قطاریں FIFO (Firs In First Out) قطار میں تھریڈز تک رسائی کی ضمانت دیتی ہیں ۔
جاوا میں Synchronous Queue استعمال کرنے والا پروڈیوسر/صارف۔
جاوا میں ہم وقت ساز قطار کی مثال - مسئلہ حل کرنا پروڈیوسر کنزیومر - 1جیسا کہ میں نے اوپر کہا، کسی بھی پروگرامنگ لینگویج میں انٹر تھریڈ کمیونیکیشن کو سمجھنے کے لیے پروڈیوسر-صارف کے مسئلے سے بہتر کوئی چیز نہیں ہے ۔ اس مسئلے میں، ایک دھاگہ ایک پروڈیوسر کے طور پر کام کرتا ہے جو واقعات اور کاموں کو تیار کرتا ہے، اور دوسرا دھاگہ اس کے صارف کے طور پر کام کرتا ہے۔ پروڈیوسر سے صارف کو ڈیٹا کی منتقلی کے لیے مشترکہ بفر استعمال کیا جاتا ہے۔ اس مسئلے کو حل کرنے میں دشواری انتہائی صورتوں میں آتی ہے، مثال کے طور پر، جب مینوفیکچرر کو انتظار کرنے پر مجبور کیا جاتا ہے کیونکہ... بفر بھرا ہوا ہے یا صارف انتظار کرنے پر مجبور ہے کیونکہ بفر خالی ہے. یہ آسانی سے حل ہو گیا، کیونکہ... بلاک کرنے والی قطار نہ صرف ڈیٹا کو ذخیرہ کرنے کے لیے ایک بفر فراہم کرتی ہے، بلکہ بہاؤ کو کنٹرول بھی کرتی ہے، اگر بفر بھرا ہوا ہو تو put() طریقہ (Producer) کو کال کرنے والے دھاگے کو بلاک کرنا، اور take() طریقہ (صارف) کو کال کرنے والے تھریڈ کو بلاک کرنا اگر بفر خالی تھا. اب ہم اسی مسئلے کو SynchronousQueue کا استعمال کرتے ہوئے حل کریں گے، جو صفر کی گنجائش کے ساتھ ایک خاص قسم کے متوازی مجموعہ ہیں۔ مندرجہ ذیل مثال میں، ہمارے پاس دو تھریڈز ہیں جنہیں PRODUCER اور CONSUMER کہتے ہیں (تھریڈز کو ہمیشہ نام دیں، یہ ملٹی تھریڈ پروگرامنگ کا بہت اچھا انداز ہے) پہلا تھریڈ گیم میں اسکور پوسٹ کرتا ہے، اور دوسرا تھریڈ اسے استعمال کرتا ہے۔ گیم میں اسکور اسٹرنگ ٹائپ کی ایک چیز سے زیادہ کچھ نہیں ہے۔ لیکن اگر آپ پروگرام کو مختلف قسم کے ساتھ چلاتے ہیں، تو آپ کو کوئی فرق محسوس نہیں ہوگا۔ یہ سمجھنے کے لیے کہ SynchronousQueue کیسے کام کرتا ہے، اور پروڈیوسر-صارف کے مسئلے کو کیسے حل کیا جائے، آپ کو یہ کرنے کی ضرورت ہے: یا تو Eclipse ماحول میں ڈیبگنگ (ڈیبگ) کے لیے پروگرام چلائیں ، یا صرف consumer.start() پر تبصرہ کرکے پروڈیوسر تھریڈ شروع کریں۔ اگر کنزیومر تھریڈ نہیں چل رہا ہے تو پروڈیوسر تھریڈ کو queue.put(event) پر بلاک کر دیا جائے گا۔ اگر چل رہا ہے، تو آپ پروڈیوسر [پروڈیوسر] کو :فور ایونٹ شائع کرتے ہوئے نہیں دیکھ پائیں گے۔ ایسا ہوتا ہے کیونکہ SynchronousQueue کا مخصوص رویہ، جو اس بات کو یقینی بناتا ہے کہ تھریڈ پوسٹ کرنے والا ڈیٹا اس وقت تک بلاک ہو جائے گا جب تک کہ کوئی دوسرا تھریڈ ڈیٹا نہ لے لے، اور اس کے برعکس۔ آپ پروڈیوسر.start() پر تبصرہ کرکے باقی کوڈ کی جانچ کر سکتے ہیں۔ اور صرف کنزیومر تھریڈ شروع کرنا۔ اگر آپ بغور مطالعہ کرتے ہیں کہ پروگرام کیا نکلتا ہے، تو آپ دیکھیں گے کہ آؤٹ پٹ کی ترتیب الٹ ہے۔ ایسا لگتا ہے کہ [CONSUMER] تھریڈ نے ڈیٹا [PRODUCER] تھریڈ تیار کرنے سے پہلے لے لیا ہے۔ اس کی وجہ یہ ہے کہ SynchronousQueue بذریعہ ڈیفالٹ قطار کی ضمانت نہیں دیتا ہے۔ لیکن اس کے منصفانہ اصول ہیں جو FIFO آرڈر میں تھریڈز تک رسائی کا تعین کرتے ہیں۔ آپ اوورلوڈ SynchronousQueue کنسٹرکٹر کو اس طرح سے گزر کر ان اصولوں کو فعال کر سکتے ہیں : import java.util.concurrent.SynchronousQueue; /** * Java Program to solve Producer Consumer problem using SynchronousQueue. A * call to put() will block until there is a corresponding thread to take() that * element. * * @author Javin Paul */ public class SynchronousQueueDemo{ public static void main(String args[]) { final SynchronousQueue queue = new SynchronousQueue (); Thread producer = new Thread("PRODUCER") { public void run() { String event = "FOUR"; try { queue.put(event); // thread will block here System.out.printf("[%s] published event : %s %n", Thread .currentThread() .getName(), event); } catch (InterruptedException e) { e.printStackTrace(); } } }; producer.start(); // starting publisher thread Thread consumer = new Thread("CONSUMER") { public void run() { try { String event = queue.take(); // thread will block here System.out.printf("[%s] consumed event : %s %n", Thread .currentThread() .getName(), event); } catch (InterruptedException e) { e.printStackTrace(); } } }; consumer.start(); // starting consumer thread } } Output: [CONSUMER] consumed event : FOUR [PRODUCER] published event : FOUR new SynchronousQueue(boolean fair).
جاوا میں SynchronousQueue کے بارے میں آپ کو کیا یاد رکھنے کی ضرورت ہے۔

جاوا میں اس خاص قسم کی بلاکنگ قطار کی کچھ اہم خصوصیات یہ ہیں۔ مطابقت پذیر طریقے سے ڈیٹا کو ایک تھریڈ سے دوسرے تھریڈ میں منتقل کرنا بہت مفید ہے۔ اس قطار میں کوئی گنجائش نہیں ہے اور اسے اس وقت تک مسدود کردیا جاتا ہے جب تک کہ دوسرا دھاگہ اسے آزاد نہ کر دے۔

  1. SynchronousQueue بلاکس، اور جب تک ایک تھریڈ ڈیٹا لینے کے لیے تیار نہ ہو، دوسرا ڈیٹا ڈالنے کی کوشش کرے گا۔
  2. SynchronousQueue کا کوئی حجم نہیں ہے۔ یعنی اس میں ڈیٹا نہیں ہے۔
  3. SynchronousQueue کا استعمال آگے کی قطار لگانے کی حکمت عملی کو نافذ کرنے کے لیے کیا جاتا ہے، جہاں ایک دھاگہ انتظار کے دھاگے کو کنٹرول کرتا ہے، یا اجازت ملنے پر ایک نیا بناتا ہے، بصورت دیگر کنٹرول منتقل نہیں ہوتا ہے۔
  4. یہ قطار null ڈیٹا کی اجازت نہیں دیتی۔ null عنصر کو شامل کرنے کی کوشش NullPointerException کو پھینک دے گی ۔
  5. اگر آپ Collection سے دوسرے طریقے استعمال کرتے ہیں (جیسے کہ پر مشتمل ہے)، SynchronousQueue ایک خالی مجموعہ کی طرح برتاؤ کرتا ہے۔
  6. آپ SynchronousQueue کا جھانکنے کا طریقہ استعمال نہیں کر سکتے کیونکہ عنصر صرف اس وقت موجود ہوتا ہے جب آپ اسے ہٹانے کی کوشش کرتے ہیں۔ نیز، آپ عناصر (کسی بھی طریقے کا استعمال کرتے ہوئے) اس وقت تک داخل نہیں کر پائیں گے جب تک کہ کوئی دوسرا تھریڈ اسے ہٹانے کی کوشش نہ کرے۔
  7. آپ SynchronousQueue کے لیے iterator استعمال نہیں کر پائیں گے کیونکہ... اس میں کوئی عناصر نہیں ہیں.
  8. SynchronousQueue کو منصفانہ اصولوں کے ساتھ بنایا جا سکتا ہے جہاں FIFO آرڈر میں تھریڈز تک رسائی کی ضمانت دی جاتی ہے۔
شاید یہ سب جاوا میں SynchronousQueue کے بارے میں ہے۔ ہم نے اس ملٹی تھریڈڈ کلیکشن کی کچھ خاص خصوصیات کو دیکھا، اور جاوا میں SynchronousQueue کا استعمال کرتے ہوئے کلاسک پروڈیوسر-صارف کے مسئلے کو حل کرنے کا طریقہ سیکھا۔ ویسے، اسے قطار کہنا بالکل درست نہیں ہے، کیونکہ... یہ عناصر پر مشتمل نہیں ہے. کال ٹو put() اس وقت تک مکمل نہیں ہوگی جب تک کہ کوئی اور تھریڈ کال نہ لے لے()۔ اسے دھاگوں کی ملاقات کی جگہ سمجھنا زیادہ درست ہے، جہاں وہ کسی چیز کا اشتراک کرتے ہیں۔ دوسرے لفظوں میں، یہ جاوا میں اشیاء کے مطابقت پذیر گزرنے کے لیے ایک افادیت ہے، شاید انتظار اور اطلاع کے طریقہ کا ایک محفوظ متبادل ۔
تبصرے
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION