جاوا: چند نخی(Multithreading) – بخش 1

شنبه ۳۰ شهریور ۹۸ توسط گیتی قاسمی

جاوا: چند نخی بخش 1

درک چند نخی 

فرآیندها در برابر نخ ها

فرآیند: چندین برنامه که بطور همزمان در سرور، سیستم شخصی یا مک اجرا می شوند.

نخ: چندین کار که در داخل یک فرآیند اجرا می شوند.

فرآیند(Process)- زمانی که یک برنامه نرم افزاری شروع به اجرا می کند، از منابع سیستمی مانند دستگاههای ورودی / خروجی، CPU، RAM، HDD و احتمالا منابع شبکه ای و نیز – سیستم عامل استفاده می کند. بطور مشابه، برنامه های نرم افزاری دیگری هم می خواهند بطور همزمان از منابع سیستمی مشابه استفاده کنند. بمنظور اشتراک گذاری منابع سیستم برای چندین برنامه نرم افزاری، این برنامه ها باید دارای مرزهای مشخصی بین یکدیگر باشند. در غیر اینصورت باعث ایجاد تداخل و مانع اجرای صحیح برنامه ها می شوند. سیستم عامل این جداسازی یا ایزوله بودن را از طریق "فرآیند ها" امکانپذیر می سازد. بدلیل اینکه چندین فرآیند می توانند همزمان اجرا شوند، چند وظیفه ای بودن سیستم عامل با استفاده از فرآیند ها انجام می گیرد.

اجرای فرآیند ها در سیستم عامل با استفاده از پردازنده (CPU)، حافظه، دیسک، و شبکه

نخ(Thread)- یک برنامه نرم افزاری،  ممکن است مجبور به انجام چند وظیفه بین رویدادهای کاربر و ذخیره کار جاری باشد. برای دستیابی به این امر، هر یک از آن وظایف باید به همان منابع سیستمی مشابهی که در دسترس فرایند است اما در فضای مخصوص خودش، دسترسی داشته باشند. مشابه با سیستم عامل، هر فرآیند قادر به ارائه این جداسازی برای چندین وظیفه که در داخل آن فرآیند قرار دارند از طریق "نخ ها" می باشد. از انجاییکه نخ های متعدد می توانند در زمان مشابه در فرآیند اجرا شوند، یک فرآیند چندوظیفه ای با استفاده از نخ ها انجام می گیرد.

 

اجرای نخ ها در داخل فرآیند جاوا (ماشین مجازی جاوا JVM)

برنامه تک نخی در مقابل چند نخی

برنامه تک نخی

قیاس: یک رستوران با 8 عضو بخش آشپزخانه در هر زمان مشخصی تنها به یک میز سرویس می دهند زیرا آنها تنها یک پیشخدمت دارند. اگر مهمانان بیشتری وجود داشته باشد، از آنها تقاضا می شود که در لابی منتظر بمانند.

مشکلات:

  • مهمانان ناامیدی که در لابی منتظر هستند.
  • منابع تلف شده در آشپزخانه.

منافع:

  • کاهش پیچیدگی – یک سفارش در هر زمان!

 

عکس توسط json leung در unsplash

برنامه تک نخی

زمان اجرا

برنامه چند نخی

قیاس: یک رستوران با 8 عضو بخش آشپزخانه که در هر زمان به 16 میز سرویس می دهد زیرا آنها 4 پیشخدمت دارند.

منافع:

  • مهمانان شاد بدلیل اینکه زمان انتظار بطور چشمگیری کاهش پیدا کرده است.
  • استفاده موثر از منابع

مشکلات:

  • پیچیدگی برنامه به دلیل منابع مشترک

همانطور که رستوران، تعداد پیشخدمت بیشتری (نخ ها) معرفی کرده است، بطور موثری از کارکنان (CORES)  آشپزخانه (CPU) بهره میبرد. در نتیجه مهمان (کاربران)  بیشتری در هر زمان خاص سرویس دهی می شوند.

این مشابه برنامه های نرم افزاری است.

اساسا بدلیل اجرای همزمان پیشرفت چشمگیری در پاسخدهی ایجاد می شود.

بطور مشابه در وظایفی که در زمان طولانی مدت اجرا می شوند می توان با تقسیم آن کار به چندین زیر وظیفه مستقل، بطور موازی در چندین نخ انجام داد که این امر باعث بهبود قابل ملاحظه ای در کارایی برنامه می شود.

برنامه چند نخی

زمان اجرا

بهبود در پاسخدهی بدلیل همزمانی، و کارایی بدلیل موازی سازی، محرکی برای برنامه های چند نخی هستند.

 

هیپ(Heap) در برابر پشته(Stack)

کدی که ما نوشته ایم بوسیله نخ (ها) اجرا می شود. زمانی که برنامه جاوا شروع بکار میکند، نخ اصلی (متد یا تابع اصلی یا همان Main Thread) بوسیله فرایند جاوا ایجاد می شود- این نقطه ورود برنامه است. از این نقطه به بعد منطق برنامه، همانظور که در بالا شرح داده شد، خواه در نخ اصلی یا نخ هایی که در داخل برنامه به بمنظور همزمان سازی یا موازی سازی ایجاد شده اند اجرا می شود.

منطق برنامه ای که بوسیله نخ ها اجرا می شود در برگیرنده محاسباتی هست که در CPU شکل می گیرد در حالی که نتایج محاسبات در RAM ذخیره می شوند.

هر نخ منتظر استفاده از یک هسته CPU برای اجرای محاسبات و یک ناحیه حافظه محلی (پشته و چندین فریم داخل هر پشته برای هر فرخوانی متد) برای ذخیره نتایج محاسبات بطور موقت خواهد بود. هنگامی که نخ اجرای کد را کامل کرد، بطور معمول نتیجه را به Heap ارسال می کند.

Heap ناحیه حافظه به اشتراک گذاری شده بین نخ ها هست، جایی که تمام اشیا در آن ساکن هستند. پشته، ناحیه حافظه خصوصی اختصاص داده شده به هر نخ در حال اجرا است.

در حافظه Heap، جمع آوری کننده زباله(Garbage collector) که برای آزادسازی فضای گرانبها، بوسیله حذف اشیایی که مدت طولانی استفاده نمی شوند (ارجاع داده شده) در داخل برنامه، مشغول به کار می‌شود. در حالی که فضای حافظه ای که توسط پشته نگهداری می شود هر باری که اجرای نخ کامل شد آزاد می شود.

Heap

به تمام اشیایی که در داخل برنامه جاوا ایجاد شده اند فضایی در حافظه اختصاص داده می شود که Heap نامیده می شود. این اشیا تا زمانی زندگی می کنند که از جایی در برنامه به آن ارجاع داده شود.

 

عکس توسط mark daynes در unsplash

پشته

نخ ها یا یک متد را اجرا می کنند و یا مجموعه ای از متدهایی را فراخوانی می کنند که فضایی در حافظه برای ذخیره متغیرهای محلی و آرگومان های متد نیاز دارند—این ناحیه حافظه، پشته گفته می شود. هر متدی که توسط نخ فراخوانی می شود بر بالای متد قبلی که فراخوانی شده است  و به آن فریم های پشته می گویند، انباشته می شود.

 

تصویر توسط Eaters Collective  در unsplash

فراخوانی پشته

نخ اصلی: متد فراخوانی پشته

قفل ها

ناظر(Monitor) و قفل(Lock)

زمانی که یک شی و وضعیتش در میان چندین نخ به اشتراک گذاشته می‌شود هر تغییر انجام شده روی وضعیت آن شی باید به عنوان یک عمل واحد (اتمی) انجام شود. در غیر اینصورت وضعیت شی توسط تغییرات همزمان خراب خواهد شد. اتمیسیته کردن، بوسیله محافظت از ناحیه بحرانی کد با یک قفل برای وادار به اجراکردن دو طرفه، بین نخ های رقیب انجام می شود.

هر شی دارای یک قفل ذاتی یا اصلی است که Monitor گفته می شود. بدلیل این ارایه زبان، قفل کردن بلوک بحرانی(critical block) کد براحتی بوسیله افزودن کلمه کلیدی انجام می شود—همگام شده(synchronized) با امضای متد(method signature). در برنامه زیر متد open از آبجکتی که از کلاس Safe ساخته شده می تواند توسط یک نخ، تنها بعد از دستیابی به قفل ذاتی دسترسی یابد__ توجه داشته باشید به کلمه کلیدی همگام شده در امضای متد(synchronized keyword in the method signature).

قفل ذاتی شناخته شده با نام ناظر 

دسترسی نخ ها به شی امن بطور پیاپی بوسیله دستیابی به قفل ذاتی 

نخی که یک متد همگام شده را اجرا می کند، گفته می شود که قفل شی را بدست آورده است. تا لحظه ای که این نخ اجرای متد را را کامل کند، هیج نخ دیگری نمیتواند این متد و یا هر متد همگام شده دیگری از این شی را اجرا کند.

اما نخی که قبلا به قفل شی دسترسی داشته است می تواند دیگر متدهای همگام شده را بدون درخواست قفل فراخوانی کند. این مکانیزم " قفل کردن بازگشتی یا همگام سازی بازگشتی" نامیده می شود.

یکی دیگر از جنبه های مهم قفل ها یا همگام سازی، برقراری یک ارتباط از قبل برقرار شده است. به این معنی که هر تغییری که روی وضعیت یک شی انجام شده است، در داخل یک بلاک همگام سازی شده، برای قابل مشاهده بودن برای دیگر نخ هایی که متعاقبا به وضعیت مشابهی بوسیله در خواست قفل مشابه دسترسی می یابند، حفاظت شده است.

دو روش برای دستیابی به قفل شی :

  • بوسیله افزودن کلید واژه همگام سازی شده روی متد همانطور که در بالا نشان داده شد.
  • به وسیله استفاده کردن از بیانیه همگام سازی شده روی "this" ، شی کلاس یا هر شی دیگری

استفاده کردن  از بیانیه همگام سازی شده، رویکرد ارجح است بدلیل اینکه این روش همه متدهای نمونه را قفل نخواهد کرد بلکه تنها آن بلوکی را که میخواهد در مقابل دسترسی همزمان حفاظت کند، قفل می کند که این امر منجر به بهبود کارایی می شود .

  • متدهای نمونه(متدهای مربوط به آبجکت ساخته شده از کلاس) روی "this" همگام سازی شده اند.
  • متد های Static روی شی Class همگام سازی شده اند.

در اصل همگام سازی (یا قفل کردن) برای جلوگیری از شرایط خطای زیر در برنامه چند نخی تاثیر گذار است:

  • تداخل نخ- چندین نخ، وضعیت یک نمونه را بطور همزمان در فرآیندی که ناشی از تفاوت زمانی آن نخ های رقیبی است که برای اجرا شدن برنامه ریزی شده‌اند، تغییر می دهند و خراب می کنند که این باعث می شود نخ ها مجموعه ای از عملکرد های مشابه را خارج از ترتیب اجرا کنند.
  • خطای ناسازگاری حافظه: نخ های خواننده می توانند داده های قدیمی را حتی زمانی که نخ نویسنده قبل از خواندن، اجرا را تکمیل کرده است مشاهده کنند. دلیل این است که نخ نویسنده مقدار تغییر داده شده را در کش CPU ذخیره خواهد کرد، بجای انتقال آن به حافظه اصلی، جایی که تمام دیگر نخ ها می توانند وضعیت بروز شده را ببینند.

زمانی که نخهای رقیبی که وضعیت تغییر پذیر مشترک را بدون هماهنگ سازی مناسب تغییر می دهد/می خواند شامل عملگرهای غیر واحد باشد، بدلیل تداخل (در هم آمیختگی) منجر به " شرایط رقابت " و " خطاهای ناسازگاری حافظه" می شود.

خلاصه

  • منابع سخت افزاری مثل CPU , RAM , HDD و دستگاههای شبکه برای برنامه های نرم افزاری بوسیله سیستم عامل برای محاسبات در دسترس قرار می گیرند.
  • این منابع در میان چندین برنامه که بطور همزمان در حال اجرا هستند به اشتراک گذاشته می شود مانند فرآیند ها در سیستم عامل. قدرت یک سیستم عامل به توانایی انجام چند کار از طریق فرایندها متکی است.
  • به همین ترتیب، یک برنامه نرم افزاری منفرد به منظور استفاده کارا از منابع سخت افزاری به عنوان یک فرایندی که باید چند کاره باشد، اجرا می شود. قدرت یک فرآیند به توانایی انجام چند کار از طریق اجرای همزمان نخ‌ها متکی است.
  • پاسخدهی از طریق همزمانی (برای مثال یک پیشخدمت به چندین کاربر بطور همزمان سرویس می دهد.)، کارایی از طریق موازی سازی (برای مثال : بکارگیری چندین HTTP end point بطور موازی برای سرویس دهی به در خواست کاربر.)، انگیزه ای برای برنامه های چند نخی هستند.
  • یک نخ در یک هسته CPU اجرا می شود. هر کد برنامه در یک نخ اجرا می شود. زمانی که یک برنامه جاوا شروع میشود، JVM متد ()main را در نخ اصلی فراخوانی می کند.
  • Heap یک ناحیه حافظه اشتراکی هست که به تمامی نخ ها برای ذخیره اشیا اختصاص داده می شود. هر نخ که یک ارجاع به شی در Heap دارد، می تواند شی را بخواند/تغییر دهد.
  • پشته ناحیه حافظه خصوصی است که به هر نخ اختصاص داده می شود (برای مثال:دو نخ یک متد کاربردی مشترک را بطور همزمان فراخوانی می کنند که متد در داخل پشته خودش جایی که متغیرهای محلی و ارگومان های متد یک نخ توسط نخ دیگر قابل مشاهده نیستند، اجرا خواهد شد.)
  • چندین نخ که به شی مشابه در Heap دسترسی دارند، باید بعد از دسترسی به قفل مشترک، به منظور جلوگیری از خرابی وضعیت شی، بطور همگام عمل کنند. 

کلیدواژه: چندنخی در جاوا MultiThreading در جاوا آموزش مالتی ترد در جاوا

منابع: blog.usejournal.com

ارسال دیدگاه:
برای ارسال دیگاه باید به سیستم وارد شوید و یا ثبت نام کنید. ثبت نام چند لحظه بیشتر زمان شما را نمیگیرد.