تعارف
تنهن ڪري، اسان ڄاڻون ٿا ته جاوا موضوع آهن. توھان ان جي باري ۾ پڙھي سگھوٿا جائزي ۾ عنوان سان گڏ بهتر: جاوا ۽ ٿريڊ ڪلاس. حصو I - عملدرآمد جا سلسلا . متوازي ڪم ڪرڻ لاءِ سلسلا ضروري آهن. انهي ڪري اهو تمام گهڻو امڪان آهي ته موضوع ڪنهن نه ڪنهن طرح هڪ ٻئي سان لهه وچڙ ۾ ايندا. اچو ته ڏسو ته اهو ڪيئن ٿئي ٿو ۽ اسان وٽ ڪهڙا بنيادي اوزار آهن.
حاصلات
Thread.yield() حيرت انگيز آهي ۽ گهٽ ۾ گهٽ استعمال ٿيل آهي. اهو انٽرنيٽ تي ڪيترن ئي مختلف طريقن سان بيان ڪيو ويو آهي. جنهن ۾ ڪجهه ماڻهو لکي رهيا آهن ته ٿريڊ جي ڪجهه قطار آهي، جنهن ۾ ٿريڊ جي ترجيحن جي بنياد تي ٿريڊ هيٺ ايندو. ٻيا ماڻهو لکن ٿا ته هڪ ٿريڊ پنهنجي حيثيت ”رننگ“ مان بدلائي ”رن ايبل“ ۾ تبديل ڪندو (جيتوڻيڪ انهن اسٽيٽسز ۾ ڪو به فرق ناهي، يعني جاوا انهن جي وچ ۾ فرق نٿو ڪري). حقيقت اها آهي ته اهو سڀ ڪجهه گهٽ مشهور آهي ۽ اڃا تائين هڪ لحاظ کان آسان آهي.
yield()
طريقي جي دستاويز لاءِ لاگ ان ٿيل آھي. جيڪڏهن توهان ان کي پڙهو، اهو واضح آهي ته اهو yield()
طريقو اصل ۾ صرف جاوا ٿريڊ شيڊولر کي ڪجهه سفارش فراهم ڪري ٿو ته هن سلسلي کي گهٽ وقت تي عمل ڪرڻ جي اجازت ڏئي سگهجي ٿي. پر اصل ۾ ڇا ٿئي ٿو، يعني ڇا شيڊيولر سفارش تي عمل ڪري ٿو ۽ عام طور تي ڇا ٿو ڪري، ان جو دارومدار JVM جي عمل درآمد ۽ آپريٽنگ سسٽم تي آهي. ۽ اهو پڻ ڪجهه ٻين عنصر تي ڀاڙي سگھي ٿو. سڀ مونجهارو گهڻو ڪري ان حقيقت جي ڪري آهي ته ملٽي ٿريڊنگ تي ٻيهر غور ڪيو ويو آهي جيئن جاوا ٻولي ترقي ڪئي آهي. جائزو ۾ وڌيڪ پڙهو هتي: جاوا جو مختصر تعارف Thread.yield()
.
سمهڻ
هڪ ڌاڳو ان جي عمل جي دوران ننڊ ۾ وڃڻ ڪري سگهو ٿا. اهو ٻين موضوعن سان رابطي جو آسان ترين قسم آهي. آپريٽنگ سسٽم جيڪو هلائي ٿو جاوا ورچوئل مشين جيڪا اسان جي جاوا ڪوڊ هلائي ٿي ان جو پنهنجو ٿريڊ شيڊيولر آهي . اهو فيصلو ڪري ٿو ته ڪهڙو سلسلو شروع ڪيو وڃي ۽ ڪڏهن. هڪ پروگرامر هن شيڊولر سان سڌو سنئون جاوا ڪوڊ مان، صرف JVM ذريعي رابطو نٿو ڪري سگهي. هو شيڊيولر کان پڇي سگھي ٿو ته موضوع کي ٿوري دير لاءِ روڪيو، يعني ان کي سمهڻ لاءِ. توھان انھن مضمونن ۾ وڌيڪ پڙھي سگھو ٿا: Thread.sleep() ۽ ڪيئن ملٽي ٿريڊنگ ڪم ڪندو آھي . توهان اهو پڻ چيڪ ڪري سگهو ٿا ته ڪئين موضوع ونڊوز آپريٽنگ سسٽم ۾ ڪم ڪن ٿا: ونڊوز ٿريڊ جا اندروني . ۽ هاڻي اچو ته ان کي پنهنجي اکين سان ڏسو. هيٺ ڏنل ڪوڊ کي فائل ۾ محفوظ ڪريو نالوHelloWorldApp.java
:
class HelloWorldApp {
public static void main(String []args) {
Runnable task = () -> {
try {
int secToWait = 1000 * 60;
Thread.currentThread().sleep(secToWait);
System.out.println("Woke up");
} catch (InterruptedException e) {
e.printStackTrace();
}
};
Thread thread = new Thread(task);
thread.start();
}
}
جئين توهان ڏسي سگهو ٿا، اسان وٽ ڪجهه ڪم آهي جيڪو 60 سيڪنڊن جو انتظار ڪري ٿو، جنهن کان پوء پروگرام ختم ٿئي ٿو. اسان ڪمانڊ " javac HelloWorldApp.java
" استعمال ڪندي گڏ ڪريون ٿا ۽ پوءِ پروگرام کي " java HelloWorldApp
" استعمال ڪري هلون ٿا. اهو بهتر آهي ته پروگرام کي هڪ الڳ ونڊو ۾ شروع ڪريو. مثال طور، ونڊوز تي، اهو هن طرح آهي: start java HelloWorldApp
. اسان پي آءِ ڊي (پروسيس آئي ڊي) حاصل ڪرڻ لاءِ jps ڪمانڊ استعمال ڪندا آهيون، ۽ اسان ٿريڊن جي لسٽ کي " jvisualvm --openpid pid
: 
try {
TimeUnit.SECONDS.sleep(60);
System.out.println("Woke up");
} catch (InterruptedException e) {
e.printStackTrace();
}
ڇا توهان محسوس ڪيو آهي ته اسان InterruptedException
هر جڳهه کي هٿ ڪري رهيا آهيون؟ اچو ته سمجھون ڇو.
Thread.interrupt()
شيء اها آهي ته جڏهن هڪ موضوع انتظار ڪري رهيو آهي / سمهڻ، ڪو ماڻهو مداخلت ڪرڻ چاهي ٿو. هن معاملي ۾، اسان کي سنڀاليوInterruptedException
. Thread.stop()
هي ميکانيزم ان طريقي کي ختم ڪرڻ کان پوءِ ٺاهيو ويو ، يعني پراڻي ۽ ناپسنديده. ان جو سبب اهو هو ته جڏهن stop()
طريقه ڪار کي سڏيو ويو ته ان سلسلي کي رڳو ”ماريو“ ڪيو ويو، جيڪو بلڪل غير متوقع هو. اسان کي خبر نه ٿي سگهي ٿي جڏهن موضوع بند ٿي ويندي، ۽ اسان ڊيٽا جي تسلسل جي ضمانت نه ڏئي سگهيا آهيون. تصور ڪريو ته توھان ھڪڙي فائل ۾ ڊيٽا لکي رھيا آھيو جڏھن تھ ٿريڊ ماريو ويو آھي. ان سلسلي کي مارڻ بجاءِ، جاوا جي تخليقڪارن فيصلو ڪيو ته ان کي ٻڌائڻ وڌيڪ منطقي هوندو ته ان ۾ مداخلت ڪئي وڃي. هن معلومات کي ڪيئن جواب ڏيڻو آهي اهو موضوع پاڻ فيصلو ڪرڻ جو موضوع آهي. وڌيڪ تفصيل لاءِ، پڙهو ڇو Thread.stop ختم ٿيل آهي؟
Oracle جي ويب سائيٽ تي. اچو ته هڪ مثال ڏسو:
public static void main(String []args) {
Runnable task = () -> {
try {
TimeUnit.SECONDS.sleep(60);
} catch (InterruptedException e) {
System.out.println("Interrupted");
}
};
Thread thread = new Thread(task);
thread.start();
thread.interrupt();
}
هن مثال ۾، اسان 60 سيڪنڊن جو انتظار نه ڪنداسين. ان جي بدران، اسان فوري طور تي "مداخلت" ڏيکارينداسين. اهو ئي سبب آهي جو اسان interrupt()
ٿريڊ تي طريقو سڏيو آهي. اهو طريقو هڪ اندروني پرچم مقرر ڪري ٿو جنهن کي "مداخلت واري صورتحال" سڏيو ويندو آهي. اهو آهي، هر سلسلي ۾ هڪ اندروني پرچم آهي جيڪو سڌو سنئون نه آهي. پر اسان وٽ هن پرچم سان لهه وچڙ لاءِ مقامي طريقا آهن. پر اهو واحد طريقو ناهي. ھڪڙو سلسلو ھلي سگھي ٿو، ڪنھن شيء جي انتظار ۾ نه، صرف عملن کي انجام ڏيڻ. پر اهو اندازو لڳائي سگھي ٿو ته ٻيا ان جي ڪم کي خاص وقت تي ختم ڪرڻ چاهيندا. مثال طور:
public static void main(String []args) {
Runnable task = () -> {
while(!Thread.currentThread().isInterrupted()) {
// Do some work
}
System.out.println("Finished");
};
Thread thread = new Thread(task);
thread.start();
thread.interrupt();
}
مٿين مثال ۾، while
لوپ تي عمل ڪيو ويندو جيستائين ڌاڳو ٻاهران مداخلت نه ڪيو وڃي. جيئن جھنڊو لاءِ isInterrupted
، اھو ڄاڻڻ ضروري آھي ته جيڪڏھن اسان ھڪ کي پڪڙيو InterruptedException
، isInterrupted پرچم ري سيٽ ٿي ويندو، ۽ پوءِ isInterrupted()
غلط موٽندو. ٿريڊ ڪلاس ۾ به ھڪ جامد Thread.interrupted()
طريقو آھي جيڪو صرف موجوده ٿريڊ تي لاڳو ٿئي ٿو، پر ھي طريقو جھنڊو کي غلط ڏانھن ري سيٽ ڪري ٿو! وڌيڪ پڙهو هن باب ۾ موضوع جي مداخلت
جي عنوان سان .
شامل ٿيو (انتظار ڪريو ٻئي سلسلي جي ختم ٿيڻ لاءِ)
انتظار جو آسان ترين قسم ٻئي سلسلي جي ختم ٿيڻ جو انتظار آهي.public static void main(String []args) throws InterruptedException {
Runnable task = () -> {
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
System.out.println("Interrupted");
}
};
Thread thread = new Thread(task);
thread.start();
thread.join();
System.out.println("Finished");
}
ھن مثال ۾، نئون موضوع 5 سيڪنڊن جي ننڊ ڪندو. ساڳئي وقت، مکيه ڌاڳو انتظار ڪندو جيستائين سمهڻ وارو سلسلو جاڳندو ۽ پنهنجو ڪم پورو ڪري. جيڪڏهن توهان JVisualVM ۾ سلسلي جي حالت تي نظر رکون ٿا، ته اهو هن طرح نظر ايندو: 
join
تمام سادو آهي، ڇاڪاڻ ته اهو صرف جاوا ڪوڊ سان هڪ طريقو آهي جيڪو wait()
ان وقت تائين هلندو آهي، جنهن تي ان کي سڏيو ويندو آهي زنده آهي. جيئن ئي ڌاڳو مري ويندو آهي (جڏهن اهو پنهنجي ڪم سان پورو ڪيو ويندو آهي)، انتظار ۾ مداخلت ڪئي وئي آهي. ۽ اهو طريقو جو سڀ جادو آهي join()
. تنهن ڪري، اچو ته سڀ کان وڌيڪ دلچسپ شيء ڏانهن وڃو.
مانيٽر
ملٽي ٿريڊنگ ۾ مانيٽر جو تصور شامل آهي. لفظ مانيٽر انگريزيءَ ۾ 16 صدي عيسويءَ جي لاطيني ٻوليءَ ۾ اچي ٿو ۽ ان جو مطلب آهي ”هڪ اوزار يا اوزار جيڪو ڪنهن عمل جي مشاهدي، جانچ، يا مسلسل رڪارڊ رکڻ لاءِ استعمال ٿيندو آهي“. هن مقالي جي حوالي سان، اسان بنيادي ڳالهين کي ڍڪڻ جي ڪوشش ڪنداسين. هر ڪنهن لاءِ جيڪو تفصيل چاهي ٿو، مهرباني ڪري ڳنڍيو مواد ۾. اسان پنھنجي سفر جي شروعات جاوا ٻوليءَ جي وضاحت (JLS) سان ڪريون ٿا: 17.1. هم وقت سازي . اهو هيٺ ڏنل چوي ٿو:
lock()
يا ان سان گڏ آزاد ڪري سگهن ٿا unlock()
. اڳيون، اسان سبق ڳولينداسين Oracle ويب سائيٽ تي: Intrinsic Locks and Synchronization
. هي سبق چوي ٿو ته جاوا جي هم وقت سازي هڪ اندروني اداري جي چوڌاري ٺهيل آهي جنهن کي اندروني تالا يا مانيٽر لاک سڏيو ويندو آهي . هي تالا اڪثر ڪري صرف " مانيٽر " سڏيو ويندو آهي. اسان وري ڏسون ٿا ته جاوا ۾ هر شئي جو ان سان لاڳاپيل هڪ اندروني تالا آهي. توھان پڙھي سگھوٿا Java - Intrinsic Locks ۽ Synchronization
. اڳتي هلي اهو سمجهڻ ضروري هوندو ته جاوا ۾ هڪ شئي مانيٽر سان ڪيئن جڙيل هجي. جاوا ۾، هر شئي جو هڪ هيڊر هوندو آهي جيڪو ذخيرو ڪري ٿو اندروني ميٽا ڊيٽا ڪوڊ مان پروگرامر وٽ دستياب ناهي، پر جنهن کي ورچوئل مشين کي صحيح طريقي سان شين سان ڪم ڪرڻ جي ضرورت آهي. اعتراض جي هيڊر ۾ "نشان لفظ" شامل آهي، جيڪو هن طرح نظر اچي ٿو: 
https://edu.netbeans.org/contrib/slides/java-overview-and-java-se6.pdf
public class HelloWorld{
public static void main(String []args){
Object object = new Object();
synchronized(object) {
System.out.println("Hello World");
}
}
}
هتي، موجوده ٿريڊ (جنهن تي ڪوڊ جون اهي لائينون لڳل آهن) synchronized
لفظ کي استعمال ڪري ٿو استعمال ڪرڻ جي ڪوشش ڪرڻ جي ڪوشش ڪرڻ لاءِ متغير سان لاڳاپيل مانيٽر object"\
تالا حاصل ڪرڻ/حاصل ڪرڻ لاءِ. جيڪڏهن ٻيو ڪو به مانيٽر لاءِ مقابلو نه ڪري رهيو آهي (يعني ٻيو ڪو به ساڳيو اعتراض استعمال ڪندي هم وقت سازي ڪوڊ نه هلائي رهيو آهي)، ته پوءِ جاوا ڪوشش ڪري سگهي ٿو هڪ اصلاح کي انجام ڏيڻ جي جنهن کي "بائيزڊ لاڪنگ" سڏيو ويندو آهي. هڪ لاڳاپيل ٽيگ ۽ هڪ رڪارڊ جنهن بابت ٿريڊ مانيٽر جي تالا جي مالڪ آهي اعتراض جي هيڊر ۾ نشان لفظ ۾ شامل ڪيا ويا آهن. هي هڪ مانيٽر کي بند ڪرڻ لاء گهربل مٿي کي گھٽائي ٿو. جيڪڏهن مانيٽر اڳ ۾ ڪنهن ٻئي سلسلي جي ملڪيت هئي، پوء اهڙي تالا ڪافي نه آهي. JVM ايندڙ قسم جي لاڪنگ ڏانھن سوئچ ڪري ٿو: "بنيادي لاڪنگ". اهو استعمال ڪري ٿو compare-and-swap (CAS) آپريشن. وڌيڪ ڇا آهي، اعتراض جي هيڊر جو نشان لفظ پاڻ هاڻي نشان لفظ کي ذخيرو نٿو ڪري، بلڪه هڪ حوالو جتي اهو ذخيرو ٿيل آهي، ۽ ٽيگ تبديل ڪري ٿو ته جيئن JVM سمجهي ته اسان بنيادي لاڪنگ استعمال ڪري رهيا آهيون. جيڪڏهن هڪ مانيٽر لاءِ ڪيترن ئي موضوعن جو مقابلو (مقابلو) ٿئي ٿو (هڪ لاڪ حاصل ڪري چڪو آهي، ۽ ٻيو لاڪ جاري ٿيڻ جو انتظار ڪري رهيو آهي)، پوءِ نشان واري لفظ ۾ ٽيگ تبديل ٿي وڃي ٿو، ۽ نشان لفظ هاڻي مانيٽر جي حوالي سان ذخيرو ڪري ٿو. هڪ اعتراض جي طور تي - JVM جو ڪجهه اندروني ادارو. جيئن JDK Enchancement Proposal (JEP) ۾ بيان ڪيو ويو آهي، هن صورتحال کي ذخيرو ڪرڻ لاءِ ميموري جي اصلي هيپ واري علائقي ۾ جاءِ جي ضرورت آهي. هن اندروني اداري جي ياداشت جي جڳهه جو حوالو اعتراض جي هيڊر جي نشان واري لفظ ۾ محفوظ ڪيو ويندو. اهڙيء طرح، هڪ مانيٽر حقيقت ۾ ڪيترن ئي موضوعن جي وچ ۾ گڏيل وسيلن تائين رسائي جي هم وقت سازي لاء هڪ ميکانيزم آهي. JVM هن ميڪانيزم جي ڪيترن ئي عملن جي وچ ۾ سوئچ ڪري ٿو. تنهن ڪري، سادگي لاء، جڏهن مانيٽر بابت ڳالهائيندي، اسان اصل ۾ تالا بابت ڳالهائي رهيا آهيون. 
هم وقت سازي (تالا جي انتظار ۾)
جيئن اسان اڳ ۾ ڏٺو، هڪ "هم وقت سازي بلاڪ" (يا "نازڪ سيڪشن") جو تصور هڪ مانيٽر جي تصور سان ويجهي سان لاڳاپيل آهي. هڪ مثال ڏسو:public static void main(String[] args) throws InterruptedException {
Object lock = new Object();
Runnable task = () -> {
synchronized(lock) {
System.out.println("thread");
}
};
Thread th1 = new Thread(task);
th1.start();
synchronized(lock) {
for (int i = 0; i < 8; i++) {
Thread.currentThread().sleep(1000);
System.out.print(" " + i);
}
System.out.println(" ...");
}
}
هتي، مکيه ٿريڊ پهريون ڀيرو ٽاسڪ اعتراض کي نئين موضوع ڏانهن منتقل ڪري ٿو، ۽ پوء فوري طور تي تالا حاصل ڪري ٿو ۽ ان سان گڏ هڪ ڊگهو آپريشن انجام ڏئي ٿو (8 سيڪنڊ). هن وقت، ڪم اڳتي وڌڻ جي قابل ناهي، ڇاڪاڻ ته اهو synchronized
بلاڪ ۾ داخل نٿو ڪري سگهي، ڇاڪاڻ ته تالا اڳ ۾ ئي حاصل ڪيو ويو آهي. جيڪڏهن موضوع تالا حاصل نه ڪري سگهي، اهو مانيٽر جو انتظار ڪندو. جيترو جلدي اهو تالا حاصل ڪري ٿو، اهو عمل جاري رکندو. جڏهن هڪ موضوع مانيٽر مان نڪرندو آهي، اهو تالا جاري ڪري ٿو. JVisualVM ۾، اهو هن طرح ڏسڻ ۾ اچي ٿو: 
th1.getState()
لوپ ۾ بيان واپس ايندو BLOCKED ، ڇاڪاڻ ته جيستائين لوپ هلندي آهي، lock
اعتراض جي مانيٽر تي قبضو ڪيو ويندو آهي main
، ۽ th1
موضوع کي بلاڪ ڪيو ويندو آهي ۽ اڳتي نه ٿو ڪري سگهجي جيستائين لاڪ جاري نه ٿئي. هم وقت سازي بلاڪ جي اضافي ۾، هڪ مڪمل طريقو هم وقت ٿي سگهي ٿو. مثال طور، هتي HashTable
ڪلاس مان هڪ طريقو آهي:
public synchronized int size() {
return count;
}
اهو طريقو ڪنهن به وقت تي صرف هڪ سلسلي ذريعي ڪيو ويندو. ڇا اسان کي واقعي تالا جي ضرورت آهي؟ ها، اسان کي ان جي ضرورت آهي. مثال جي طريقن جي صورت ۾، "هي" اعتراض (موجوده اعتراض) هڪ تالا طور ڪم ڪري ٿو. هتي هن موضوع تي هڪ دلچسپ بحث آهي: ڇا هڪ هم وقت سازي بلاڪ جي بدران هڪ هم وقت سازي طريقو استعمال ڪرڻ جو ڪو فائدو آهي؟
. جيڪڏهن طريقو جامد آهي، ته تالا "هي" اعتراض نه هوندو (ڇاڪاڻ ته جامد طريقي لاء ڪو به "هي" اعتراض ناهي)، بلڪه هڪ طبقاتي اعتراض (مثال طور، ) Integer.class
.
انتظار ڪريو (مانيٽر جي انتظار ۾). اطلاع () ۽ سڀني () طريقن کي اطلاع ڏيو
ٿريڊ ڪلاس وٽ هڪ ٻيو انتظار جو طريقو آهي جيڪو مانيٽر سان جڙيل آهي. برعڪسsleep()
۽ join()
، هن طريقي کي صرف نه ٿو سڏيو وڃي. ان جو نالو آهي wait()
. طريقي wait
کي سڏيو ويندو آهي مانيٽر سان لاڳاپيل اعتراض تي جيڪو اسان انتظار ڪرڻ چاهيون ٿا. اچو ته هڪ مثال ڏسون:
public static void main(String []args) throws InterruptedException {
Object lock = new Object();
// The task object will wait until it is notified via lock
Runnable task = () -> {
synchronized(lock) {
try {
lock.wait();
} catch(InterruptedException e) {
System.out.println("interrupted");
}
}
// After we are notified, we will wait until we can acquire the lock
System.out.println("thread");
};
Thread taskThread = new Thread(task);
taskThread.start();
// We sleep. Then we acquire the lock, notify, and release the lock
Thread.currentThread().sleep(3000);
System.out.println("main");
synchronized(lock) {
lock.notify();
}
}
JVisualVM ۾، اهو هن طرح ڏسڻ ۾ اچي ٿو: 
wait()
۽ notify()
طريقا سان لاڳاپيل آهن java.lang.Object
. اهو عجيب لڳي سگھي ٿو ته موضوع سان لاڳاپيل طريقا ڪلاس ۾ آهن Object
. پر ان جو سبب هاڻي سامهون اچي رهيو آهي. توهان کي ياد هوندو ته جاوا ۾ هر شئي جو هيڊر هوندو آهي. هيڊر مختلف گھر جي سنڀال جي معلومات تي مشتمل آهي، بشمول مانيٽر بابت معلومات، يعني تالا جي حالت. ياد رکو، هر شئي، يا ڪلاس جو مثال، JVM ۾ هڪ اندروني اداري سان جڙيل آهي، جنهن کي اندروني تالا يا مانيٽر سڏيو ويندو آهي. مٿين مثال ۾، ٽاسڪ اعتراض لاءِ ڪوڊ اشارو ڪري ٿو ته اسان lock
اعتراض سان لاڳاپيل مانيٽر لاءِ هم وقت ساز بلاڪ داخل ڪريون ٿا. جيڪڏهن اسان هن مانيٽر لاء تالا حاصل ڪرڻ ۾ ڪامياب ٿي، پوء wait()
سڏيو ويندو آهي. ٽاسڪ تي عمل ڪرڻ وارو سلسلو lock
اعتراض جي مانيٽر کي جاري ڪندو، پر اعتراض جي مانيٽر کان نوٽيفڪيشن جي انتظار ۾ سلسلي جي قطار ۾ داخل ٿيندو lock
. سلسلي جي هن قطار کي WAIT SET چئبو آهي، جيڪو وڌيڪ صحيح نموني پنهنجي مقصد کي ظاهر ڪري ٿو. اهو آهي، اهو هڪ قطار کان وڌيڪ هڪ سيٽ آهي. موضوع main
ٽاسڪ اعتراض سان هڪ نئون ٿريڊ ٺاهي ٿو، ان کي شروع ڪري ٿو، ۽ 3 سيڪنڊن جو انتظار ڪري ٿو. انهي ڪري اهو تمام گهڻو امڪان آهي ته نئين ٿريڊ ٿريڊ کان اڳ لاڪ حاصل ڪرڻ جي قابل ٿي ويندي main
، ۽ مانيٽر جي قطار ۾ داخل ٿي ويندي. ان کان پوء، main
ڌاڳو پاڻ کي lock
اعتراض جي هم وقت سازي واري بلاڪ ۾ داخل ٿئي ٿو ۽ مانيٽر کي استعمال ڪندي ٿريڊ نوٽيفڪيشن انجام ڏئي ٿو. نوٽيفڪيشن موڪلڻ کان پوءِ، main
ٿريڊ اعتراض جي مانيٽر کي جاري ڪري ٿو lock
، ۽ نئون ٿريڊ، جيڪو اڳ ۾ lock
اعتراض جي مانيٽر جي جاري ٿيڻ جو انتظار ڪري رهيو هو، عمل جاري رکي ٿو. اهو ممڪن آهي ته هڪ نوٽيفڪيشن صرف هڪ سلسلي ( notify()
) ڏانهن يا هڪ ئي وقت قطار ۾ سڀني موضوعن ڏانهن موڪليو وڃي ( notifyAll()
). وڌيڪ پڙهو هتي: جاوا ۾ notify() ۽ notifyAll() جي وچ ۾ فرق
. اهو نوٽ ڪرڻ ضروري آهي ته نوٽيفڪيشن آرڊر ان تي منحصر آهي ته JVM ڪيئن لاڳو ٿئي ٿي. وڌيڪ پڙهو هتي: نوٽيفڪيشن ۽ سڀني کي اطلاع ڏيڻ سان بک کي ڪيئن حل ڪجي؟
. هم وقت سازي کي بغير ڪنهن اعتراض جي وضاحت ڪري سگهجي ٿو. توهان اهو ڪري سگهو ٿا جڏهن مڪمل طريقي سان هم وقت سازي ڪئي وئي آهي بلڪه ڪوڊ جي هڪ بلاڪ جي. مثال طور، جامد طريقن لاءِ، تالا هڪ ڪلاس شئي هوندو (حاصل ڪيل ذريعي .class
):
public static synchronized void printA() {
System.out.println("A");
}
public static void printB() {
synchronized(HelloWorld.class) {
System.out.println("B");
}
}
تالا استعمال ڪرڻ جي لحاظ کان، ٻئي طريقا ساڳيا آهن. جيڪڏهن ڪو طريقو جامد نه آهي، ته پوءِ هم وقت سازي ڪئي ويندي موجوده استعمال ڪندي instance
، يعني استعمال ڪندي this
. رستي ۾، اسان اڳ ۾ چيو آهي ته توهان getState()
هڪ موضوع جي حيثيت حاصل ڪرڻ لاء طريقو استعمال ڪري سگهو ٿا. مثال طور، مانيٽر جي انتظار ۾ قطار ۾ هڪ سلسلي لاءِ، اسٽيٽس WAITING يا TIMED_WAITING ٿي ويندي، جيڪڏهن طريقو wait()
وقت ختم ڪيو ويو آهي. 
https://stackoverflow.com/questions/36425942/what-is-the-lifecycle-of-thread-in-java
زندگيءَ جو سلسلو
ان جي زندگي جي دوران، هڪ سلسلي جي حيثيت تبديل ٿي. حقيقت ۾، اهي تبديليون موضوع جي زندگيء جي چڪر تي مشتمل آهن. جيئن ئي ڪو ٿريڊ ٺهي ٿو ته ان جي حيثيت نئين ٿي وڃي ٿي. هن حالت ۾، نئون سلسلو اڃا تائين نه هلندو آهي ۽ جاوا موضوع شيڊولر اڃا تائين ان بابت ڪجهه به نه ڄاڻندو آهي. ٿريڊ شيڊيولر لاءِ ٿريڊ جي باري ۾ سکڻ لاءِ، توھان کي سڏڻ گھرجيthread.start()
طريقو. ان کان پوء موضوع RUNNABLE رياست ڏانهن منتقل ٿيندو. انٽرنيٽ ۾ ڪيترائي غلط ڊراگرام آھن جيڪي "رننبل" ۽ "رننگ" رياستن جي وچ ۾ فرق ڪن ٿا. پر هي هڪ غلطي آهي، ڇاڪاڻ ته جاوا "ڪم ڪرڻ لاء تيار" (رننبل) ۽ "ڪم ڪرڻ" (هلندڙ) جي وچ ۾ فرق نٿو ڪري. جڏهن هڪ ڌاڳو زنده آهي پر فعال نه آهي (چلڻ لائق نه آهي)، اهو ٻن رياستن مان هڪ ۾ آهي:
- بلاڪ ٿيل - هڪ نازڪ حصي ۾ داخل ٿيڻ جي انتظار ۾، يعني هڪ
synchronized
بلاڪ. - انتظار - ڪنهن شرط کي پورو ڪرڻ لاءِ ٻئي سلسلي جو انتظار.
getState()
طريقو استعمال ڪريو. موضوعن ۾ پڻ ھڪڙو isAlive()
طريقو آھي، جيڪو صحيح موٽائي ٿو جيڪڏھن موضوع ختم نه ڪيو ويو آھي.
LockSupport ۽ موضوع پارڪنگ
جاوا 1.6 سان شروع ڪندي، هڪ دلچسپ ميکانيزم سڏيو ويندو آهي LockSupport .
park()
فوري طور تي واپس اچي ٿو جيڪڏهن پرمٽ موجود آهي، پروسيس ۾ پرمٽ استعمال ڪندي. ٻي صورت ۾، بلاڪ. طريقي کي ڪال ڪرڻ unpark
جي اجازت ڏئي ٿي جيڪڏهن اهو اڃا تائين دستياب ناهي. اتي صرف 1 پرمٽ آهي. جاوا دستاويز طبقن LockSupport
جي حوالي سان Semaphore
. اچو ته هڪ سادي مثال ڏسو:
import java.util.concurrent.Semaphore;
public class HelloWorldApp{
public static void main(String[] args) {
Semaphore semaphore = new Semaphore(0);
try {
semaphore.acquire();
} catch (InterruptedException e) {
// Request the permit and wait until we get it
e.printStackTrace();
}
System.out.println("Hello, World!");
}
}
هي ڪوڊ هميشه انتظار ڪندو، ڇاڪاڻ ته هاڻي سيمفور کي 0 اجازتون آهن. ۽ جڏهن acquire()
ڪوڊ ۾ سڏيو ويندو آهي (يعني پرمٽ جي درخواست ڪريو)، اهو سلسلو انتظار ڪري ٿو جيستائين اهو پرمٽ حاصل ڪري. جيئن ته اسان انتظار ڪري رهيا آهيون، اسان کي سنڀالڻ گهرجي InterruptedException
. دلچسپ ڳالهه اها آهي ته سيمفور هڪ الڳ ٿريڊ اسٽيٽ حاصل ڪري ٿو. جيڪڏهن اسان JVisualVM ۾ ڏسون ٿا، اسان ڏسنداسين ته رياست "انتظار" نه آهي، پر "پارڪ". 
public static void main(String[] args) throws InterruptedException {
Runnable task = () -> {
// Park the current thread
System.err.println("Will be Parked");
LockSupport.park();
// As soon as we are unparked, we will start to act
System.err.println("Unparked");
};
Thread th = new Thread(task);
th.start();
Thread.currentThread().sleep(2000);
System.err.println("Thread state: " + th.getState());
LockSupport.unpark(th);
Thread.currentThread().sleep(2000);
}
موضوع جي حيثيت WAITING هوندي، پر JVisualVM لفظ ۽ ڪلاس جي وچ ۾ wait
فرق synchronized
ڪري park
ٿو LockSupport
. هي LockSupport
ايترو اهم ڇو آهي؟ اسان ٻيهر جاوا دستاويزن ڏانهن ڦيرايو ۽ WAITING
ٿريڊ اسٽيٽ کي ڏسو. جئين توهان ڏسي سگهو ٿا، ان ۾ حاصل ڪرڻ لاء صرف ٽي طريقا آهن. انهن مان ٻه طريقا آهن wait()
۽ join()
. ۽ ٽيون آهي LockSupport
. جاوا ۾، تالا پڻ ٺاهي سگھجن ٿا LockSuppor
ٽي تي ۽ پيش ڪن ٿا اعلي سطحي اوزار. اچو ته ھڪڙو استعمال ڪرڻ جي ڪوشش ڪريو. مثال طور، هڪ نظر وٺو ReentrantLock
:
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class HelloWorld{
public static void main(String []args) throws InterruptedException {
Lock lock = new ReentrantLock();
Runnable task = () -> {
lock.lock();
System.out.println("Thread");
lock.unlock();
};
lock.lock();
Thread th = new Thread(task);
th.start();
System.out.println("main");
Thread.currentThread().sleep(2000);
lock.unlock();
}
}
جيئن ته پوئين مثالن ۾، هتي هر شيء سادو آهي. اعتراض lock
ڪنهن جي انتظار ۾ آهي حصيداري وسيلن کي ڇڏڻ لاء. جيڪڏهن اسان JVisualVM ۾ ڏسون ٿا، اسان ڏسنداسين ته نئون ٿريڊ پارڪ ڪيو ويندو جيستائين ٿريڊ main
ان کي بند نه ڪري. توهان لاڪ بابت وڌيڪ پڙهي سگهو ٿا هتي: Java 8 StampedLocks vs. ReadWriteLocks ۽ Synchronized
and Lock API جاوا ۾. بهتر سمجھڻ لاءِ ته لاڪ ڪيئن لاڳو ڪيا وڃن ٿا، اھو مددگار آھي ھن مضمون ۾ Phaser بابت پڙھو: Guide to the Java Phaser
. ۽ مختلف هم وقت سازن جي باري ۾ ڳالهائڻ، توهان کي ضرور پڙهڻ گهرجي DZone آرٽيڪل
تي جاوا سنڪرونائزرز.
نتيجو
هن جائزي ۾، اسان بنيادي طريقن جو جائزو ورتو ته موضوع جاوا ۾ لهه وچڙ ۾. اضافي مواد:- گڏو گڏ بهتر: جاوا ۽ ٿريڊ ڪلاس. حصو I - عملدرآمد جا سلسلا
- https://dzone.com/articles/the-java-synchronizers
- https://www.javatpoint.com/java-multithreading-interview-questions
GO TO FULL VERSION