6. Cancarenzi کیا ہے؟
Concurrency جاوا میں ایک کلاس لائبریری ہے جس میں ایک سے زیادہ تھریڈز میں کام کرنے کے لیے موزوں خصوصی کلاسز شامل ہیں۔ یہ کلاسیں ایک پیکج میں جمع کی جاتی ہیںjava.util.concurrent
۔ ان کو فنکشنلٹی کے مطابق اس طرح تقسیم کیا جا سکتا ہے: کنکرنٹ کلیکشنز - مجموعوں کا ایک مجموعہ جو java.util
پیکج سے معیاری یونیورسل کلیکشنز کے مقابلے کثیر تھریڈ والے ماحول میں زیادہ مؤثر طریقے سے کام کرتا ہے۔ پورے مجموعہ تک رسائی کو مسدود کرنے والے بنیادی ریپر کے بجائے Collections.synchronizedList
، ڈیٹا سیگمنٹس پر لاک استعمال کیے جاتے ہیں، یا انتظار سے پاک الگورتھم کا استعمال کرتے ہوئے ڈیٹا کی متوازی پڑھنے کے لیے کام کو بہتر بنایا جاتا ہے۔ قطاریں - ملٹی تھریڈنگ سپورٹ کے ساتھ نان بلاکنگ اور بلاکنگ قطار۔ غیر مسدود قطاریں دھاگوں کو بلاک کیے بغیر رفتار اور آپریشن کے لیے ڈیزائن کی گئی ہیں۔ مسدود کرنے والی قطاریں اس وقت استعمال ہوتی ہیں جب آپ کو "پروڈیوسر" یا "صارف" تھریڈز کو "سست" کرنے کی ضرورت ہوتی ہے اگر کچھ شرائط پوری نہیں ہوتی ہیں، مثال کے طور پر، قطار خالی ہے یا بھری ہوئی ہے، یا کوئی مفت "صارف" نہیں ہے۔ سنکرونائزر تھریڈز کو سنکرونائز کرنے کے لیے معاون یوٹیلیٹیز ہیں۔ وہ "متوازی" کمپیوٹنگ میں ایک طاقتور ہتھیار ہیں۔ ایگزیکیوٹرز - تھریڈ پول بنانے، غیر مطابقت پذیر کاموں کو شیڈول کرنے اور نتائج حاصل کرنے کے لیے بہترین فریم ورک پر مشتمل ہے۔ تالے - بنیادی کے مقابلے متبادل اور زیادہ لچکدار دھاگے کی مطابقت پذیری کے طریقہ کار کی synchronized
نمائندگی wait
کرتا ہے notify
۔ جوہری - قدیم اور حوالہ جات پر جوہری آپریشن کے لیے معاونت کے ساتھ کلاسز۔ ذریعہ:notifyAll
7. آپ کنکرنسی سے کون سی کلاسز جانتے ہیں؟
اس سوال کا جواب اس مضمون میں مکمل طور پر بیان کیا گیا ہے ۔ مجھے یہاں یہ سب دوبارہ شائع کرنے کا کوئی فائدہ نظر نہیں آتا، اس لیے میں صرف ان کلاسوں کی تفصیل پیش کروں گا جن سے مجھے مختصراً آشنا ہونے کا اعزاز حاصل تھا۔ ConcurrentHashMap<K, V> - کے برعکسHashtable
اور بلاکس synhronized
آن HashMap
، ڈیٹا کو سیگمنٹس کی شکل میں پیش کیا جاتا ہے، کیز کی ہیشز میں تقسیم کیا جاتا ہے۔ نتیجے کے طور پر، ڈیٹا تک رسائی واحد آبجیکٹ کے بجائے طبقات کے ذریعے کی جاتی ہے۔ اس کے علاوہ، تکرار کرنے والے ایک مخصوص مدت کے لیے ڈیٹا کی نمائندگی کرتے ہیں اور پھینکتے نہیں ہیں ConcurrentModificationException
۔ AtomicBoolean, AtomicInteger, AtomicLong, AtomicIntegerArray, AtomicLongArray - کیا ہوگا اگر کسی کلاس میں آپ کو قسم کے ایک سادہ متغیر تک رسائی کو ہم آہنگ کرنے کی ضرورت ہو int
؟ آپ تعمیرات کے ساتھ استعمال کر سکتے ہیں ، synchronized
اور جب ایٹمک آپریشنز استعمال کرتے ہیں set/get
، volatile
لیکن آپ نئی کلاسیں استعمال کر کے اور بھی بہتر کر سکتے ہیں Atomic*
۔ CAS کے استعمال کی وجہ سے، ان کلاسوں کے ساتھ آپریشنز اس کے مقابلے میں تیز تر ہوتے ہیں اگر ہم بذریعہ مطابقت پذیر ہوں synchronized/volatile
۔ اس کے علاوہ، ایک دی گئی رقم سے جوہری اضافے کے ساتھ ساتھ انکریمنٹ/کمی کے طریقے بھی موجود ہیں۔
8. ConcurrentHashMap کلاس کیسے کام کرتی ہے؟
اس کے تعارف کے وقت تک،ConcurrentHashMap
جاوا ڈویلپرز کو درج ذیل ہیش میپ کے نفاذ کی ضرورت تھی۔
- دھاگے کی حفاظت
- اس تک رسائی کے دوران پوری میز پر کوئی تالے نہیں ہیں۔
- یہ ضروری ہے کہ ریڈنگ آپریشن کرتے وقت کوئی ٹیبل تالے نہ ہوں۔
ConcurrentHashMap
مندرجہ ذیل ہیں:
-
نقشے کے عناصر
عناصر کے برعکس
HashMap
،Entry
میںConcurrentHashMap
کو قرار دیا جاتا ہےvolatile
۔ JMM میں تبدیلیوں کی وجہ سے بھی یہ ایک اہم خصوصیت ہے ۔static final class HashEntry<K, V> { final K key; final int hash; volatile V value; final HashEntry<K, V> next; HashEntry(K key, int hash, HashEntry<K, V> next, V value) { this .key = key; this .hash = hash; this .next = next; this .value = value; } @SuppressWarnings("unchecked") static final <K, V> HashEntry<K, V>[] newArray(int i) { return new HashEntry[i]; } }
-
ہیش فنکشن
ConcurrentHashMap
ایک بہتر ہیشنگ فنکشن بھی استعمال کیا جاتا ہے۔HashMap
میں آپ کو یاد دلاتا ہوں کہ یہ JDK 1.2 میں کیسا تھا :static int hash(int h) { h ^= (h >>> 20) ^ (h >>> 12); return h ^ (h >>> 7) ^ (h >>> 4); }
ConcurrentHashMap JDK 1.5 سے ورژن:
private static int hash(int h) { h += (h << 15) ^ 0xffffcd7d; h ^= (h >>> 10); h += (h << 3); h ^= (h >>> 6); h += (h << 2) + (h << 14); return h ^ (h >>> 16); }
ہیش فنکشن کو مزید پیچیدہ بنانے کی ضرورت کیوں ہے؟ ہیش میپ میں ٹیبلز کی لمبائی دو کی طاقت سے متعین ہوتی ہے۔ ہیش کوڈز کے لیے جن کی بائنری نمائندگی کم اور اونچی پوزیشن میں مختلف نہیں ہوتی، ہمارے پاس تصادم ہوگا۔ ہیش فنکشن کی پیچیدگی میں اضافہ صرف اس مسئلے کو حل کرتا ہے، نقشے میں تصادم کے امکانات کو کم کرتا ہے۔
-
طبقات
نقشہ کو N مختلف حصوں میں تقسیم کیا گیا ہے (16 بطور ڈیفالٹ، زیادہ سے زیادہ قدر 16 بٹس ہو سکتی ہے اور اس کی طاقت دو ہے)۔ ہر سیگمنٹ نقشہ کے عناصر کا ایک دھاگے سے محفوظ جدول ہے۔ سیگمنٹس کی تعداد میں اضافہ متعدد سیگمنٹس کو پھیلانے کے لیے ترمیمی کارروائیوں کی حوصلہ افزائی کرے گا، جس سے رن ٹائم پر بلاک ہونے کے امکانات کم ہوں گے۔
-
کنکرنسی لیول
یہ پیرامیٹر میموری کارڈ کے استعمال اور کارڈ میں سیگمنٹس کی تعداد کو متاثر کرتا ہے۔
حصوں کی تعداد کو کنکرنسی لیول سے زیادہ دو کی قریب ترین طاقت کے طور پر منتخب کیا جائے گا۔ کنکرنسی لیول کو کم کرنے سے اس بات کا زیادہ امکان ہوتا ہے کہ لکھتے وقت تھریڈز نقشہ کے حصوں کو روک دیں گے۔ اشارے کا زیادہ اندازہ میموری کے غیر موثر استعمال کا باعث بنتا ہے۔ اگر صرف ایک دھاگہ نقشے میں ترمیم کرے گا، اور باقی پڑھے گا، تو یہ تجویز کی جاتی ہے کہ قدر 1 استعمال کریں۔
-
کل
لہذا، اہم فوائد اور نفاذ کی خصوصیات
ConcurrentHashMap
:hashmap
نقشے میں ایک تعامل انٹرفیس جیسا ہے۔- پڑھنے کی کارروائیوں کو تالے کی ضرورت نہیں ہوتی ہے اور یہ متوازی طور پر انجام دی جاتی ہیں۔
- تحریری کارروائیاں اکثر بلاک کیے بغیر متوازی طور پر بھی کی جا سکتی ہیں۔
- تخلیق کرتے وقت، مطلوبہ کی نشاندہی کی جاتی ہے
concurrencyLevel
، اس کا تعین اعداد و شمار کو پڑھنے اور لکھ کر کیا جاتا ہے۔ - نقشہ کے عناصر کی ایک قدر ہے
value
جس کا اعلان کیا گیا ہے۔volatile
9. لاک کلاس کیا ہے؟
مشترکہ وسائل تک رسائی کو کنٹرول کرنے کے لیے، ہم مطابقت پذیر آپریٹر کے متبادل کے طور پر تالے استعمال کر سکتے ہیں۔ لاکنگ کی فعالیت میں پیک کیا گیا ہےjava.util.concurrent.locks
۔ سب سے پہلے، تھریڈ مشترکہ وسائل تک رسائی حاصل کرنے کی کوشش کرتا ہے۔ اگر یہ مفت ہے، تو دھاگے پر ایک تالا لگا دیا جاتا ہے. ایک بار کام مکمل ہونے کے بعد، مشترکہ وسائل پر لاک جاری ہو جاتا ہے۔ اگر وسیلہ مفت نہیں ہے اور اس پر پہلے ہی ایک تالا لگا ہوا ہے، تو دھاگہ اس تالے کے جاری ہونے تک انتظار کرتا ہے۔ لاک کلاسز ایک انٹرفیس کو نافذ کرتی ہیں Lock
جو درج ذیل طریقوں کی وضاحت کرتی ہے۔
void lock():
تالے کے حاصل ہونے تک انتظار کرتا ہے۔boolean tryLock():
ایک تالا حاصل کرنے کی کوشش کرتا ہے؛ اگر تالا حاصل کیا جاتا ہے، تو یہ درست ہو جاتا ہے ۔ اگر تالا حاصل نہیں کیا جاتا ہے، تو یہ غلط واپس آتا ہے ۔ طریقہ کے برعکس،lock()
اگر کوئی دستیاب نہ ہو تو یہ تالا حاصل کرنے کا انتظار نہیں کرتاvoid unlock():
تالا ہٹاتا ہےCondition newCondition():
وہ آبجیکٹ لوٹاتا ہےCondition
جو موجودہ لاک سے وابستہ ہے۔
lock()
، اور مشترکہ وسائل کے ساتھ کام کرنے کے بعد، طریقہ کہا جاتا ہے unlock()
، جو تالے کو جاری کرتا ہے. آبجیکٹ Condition
آپ کو بلاکنگ کا انتظام کرنے کی اجازت دیتا ہے۔ ایک اصول کے طور پر، تالے کے ساتھ کام کرنے کے لیے، ReentrantLock
پیکیج سے ایک کلاس استعمال کی جاتی ہے۔ java.util.concurrent.locks.
یہ کلاس انٹرفیس کو نافذ کرتی ہے Lock
۔ آئیے مثال کے طور پر ایک چھوٹے سے پروگرام کا استعمال کرتے ہوئے جاوا لاک API کا استعمال کرتے ہوئے دیکھتے ہیں: تو، ہم کہتے ہیں کہ ہمارے پاس Resource
تھریڈ سیف طریقوں اور طریقوں کے ساتھ ایک کلاس ہے جہاں تھریڈ سیفٹی کی ضرورت نہیں ہے۔
public class Resource {
public void doSomething(){
// пусть здесь происходит работа с базой данных
}
public void doLogging(){
// потокобезопасность для логгирования нам не требуется
}
}
اب ایک کلاس لیتے ہیں جو انٹرفیس کو لاگو کرتی ہے Runnable
اور کلاس کے طریقے استعمال کرتی ہے Resource
۔
public class SynchronizedLockExample implements Runnable{
// экземпляр класса Resource для работы с методами
private Resource resource;
public SynchronizedLockExample(Resource r){
this.resource = r;
}
@Override
public void run() {
synchronized (resource) {
resource.doSomething();
}
resource.doLogging();
}
}
اب اوپر والے پروگرام کو لاک API کے بجائے دوبارہ لکھتے ہیں synchronized
۔
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
// класс для работы с Lock API. Переписан с приведенной выше программы,
// но уже без использования ключевого слова synchronized
public class ConcurrencyLockExample implements Runnable{
private Resource resource;
private Lock lock;
public ConcurrencyLockExample(Resource r){
this.resource = r;
this.lock = new ReentrantLock();
}
@Override
public void run() {
try {
// лочим на 10 секунд
if(lock.tryLock(10, TimeUnit.SECONDS)){
resource.doSomething();
}
} catch (InterruptedException e) {
e.printStackTrace();
}finally{
//убираем лок
lock.unlock();
}
// Для логгирования не требуется потокобезопасность
resource.doLogging();
}
}
جیسا کہ آپ پروگرام سے دیکھ سکتے ہیں، ہم اس tryLock()
بات کو یقینی بنانے کے لیے طریقہ استعمال کرتے ہیں کہ تھریڈ صرف ایک خاص وقت تک انتظار کرے۔ اگر یہ آبجیکٹ پر تالا حاصل نہیں کرتا ہے، تو یہ آسانی سے لاگ اور باہر نکل جاتا ہے۔ ایک اور اہم نکتہ۔ آپ کو اس بات کو یقینی بنانے کے لیے ایک بلاک کا استعمال کرنا چاہیے try-finally
کہ تالے کو جاری کیا جائے گا چاہے طریقہ doSomething()
مستثنیٰ ہو۔ ذرائع:
11. ایک mutex کیا ہے؟
ایک mutex دھاگوں / عمل کو مطابقت پذیر کرنے کے لئے ایک خاص چیز ہے۔ یہ دو ریاستیں لے سکتا ہے - مصروف اور مفت۔ آسان بنانے کے لیے، ایک mutex ایک بولین متغیر ہے جو دو اقدار لیتا ہے: مصروف (سچ) اور مفت (غلط)۔ جب کوئی دھاگہ کسی شے کی خصوصی ملکیت چاہتا ہے، تو وہ اپنے mutex کو مصروف کے طور پر نشان زد کرتا ہے، اور جب اس کے ساتھ کام ختم ہوجاتا ہے، تو یہ اپنے mutex کو مفت کے طور پر نشان زد کرتا ہے۔ جاوا میں ہر شے کے ساتھ ایک mutex منسلک ہوتا ہے۔ صرف جاوا مشین کو ہی mutex تک براہ راست رسائی حاصل ہے۔ یہ پروگرامر سے پوشیدہ ہے۔12. مانیٹر کیا ہے؟
مانیٹر ایک خاص طریقہ کار ہے (کوڈ کا ایک ٹکڑا) - میوٹیکس پر ایک ایڈ آن، جو اس کے ساتھ درست آپریشن کو یقینی بناتا ہے۔ سب کے بعد، یہ نشان زد کرنا کافی نہیں ہے کہ اعتراض مصروف ہے؛ ہمیں یہ بھی یقینی بنانا چاہیے کہ دوسرے تھریڈز مصروف چیز کو استعمال کرنے کی کوشش نہ کریں۔ جاوا میں، مانیٹر کو کلیدی لفظ کا استعمال کرتے ہوئے لاگو کیا جاتا ہےsynchronized
۔ جب ہم ایک مطابقت پذیر بلاک لکھتے ہیں، تو جاوا کمپائلر اسے کوڈ کے تین ٹکڑوں سے بدل دیتا ہے۔
- بلاک کے شروع میں
synchronized
، کوڈ شامل کیا جاتا ہے جو mutex کو مصروف کے طور پر نشان زد کرتا ہے۔ - بلاک کے آخر میں،
synchronized
ایک کوڈ شامل کیا جاتا ہے جو mutex کو مفت کے طور پر نشان زد کرتا ہے۔ - بلاک سے پہلے،
synchronized
کوڈ شامل کیا جاتا ہے جو چیک کرتا ہے کہ آیا mutex مصروف ہے، پھر تھریڈ کو اس کے جاری ہونے کا انتظار کرنا چاہیے۔
GO TO FULL VERSION