مفهوم Thread در برنامه نویسی چیست
علمی و تکنولوژی › نرم افزار
- 99/03/14مفهوم Thread در برنامه نویسی موضوع مورد بحث ماست. برای افزایش سرعت و همچنین بهینه سازی برنامه می توانیم از برنامه نویسی چند نخی «Thread» استفاده نماییم. با این کار می توانیم وظایف برنامه را به چند قسمت تقسیم و به طور همزمان انجام بدهیم تا سرعت بالاتری برای برنامه رقم بزنیم. برنامه نویسی چند نخی یکی از اساسی ترین و مهمترین ارکان برنامه نویسی می باشد که متأسفانه حتی بسیاری از برنامه نویسان حرفه ای نیز آن را نادیده می گیرند. چرا که با وجود سرعت های بالای CPU در سخت افزارهای PC و Notebook نیاز به استفاده از Thread ها به چشم نمی آید اما یکی از بزرگترین دلایل وجود Hang و در نتیجه Crash ها عدم توجه به این تکنیک برنامه نویسی می باشد. در دستگاه های ضعیف تر نظیر Smart Phone ها استفاده از Thread ها بسیار واجب و ضروری می باشد و حتی برای انجام هر عمل کم زمانبر نیز استفاده از Thread ها اکیداً توصیه می گردد.
تکنیک های Thread در اندروید
از آنجا که Thread ها پس از انجام یک کار خاتمه می یابند، باید نوعی حلقه برای زنده نگه داشتن آنها در اختیار داشته باشیم. همچنین باید بتوانیم در زمان نیاز هم آنها را خاتمه ببخشیم. علاوه بر آن باید نوعی صف نیز داشته باشیم که حلقه موصوف بتواند کارها را از روی آن بردارد. ضمناً نیازمند نوعی Thread دیگر نیز هستیم که بسته های کاری را ایجاد کرده و آنها را به صف اجرایی وارد کند. انجام همه این کارها و نگهداری حالتهای آن موجب ایجاد پیچیدگی زیادی میشود. با این حال اندروید روش های کار با Thread ها ارائه کرده است. زمانی که یک اپلیکیشن اجرا میشود، اندروید پردازش لینوکس مخصوص آن را ایجاد میکند. علاوه بر آن، سیستم یک نخ اجرایی نیز برای آن اپلیکیشن علاوه بر «نخ اصلی» (main thread) و «نخ UI» نیز (UI thread) میسازد. نخ اصلی چیزی به جز یک نخ مدیریت کننده نیست. نخ اصلی مسئول مدیریت رویدادهای رخ داده در همه جای اپلیکیشن مانند callback-های مرتبط با اطلاعات چرخه عمری یا callback-های رویدادهای ورودی است. همچنین میتواند رویدادهای رسیده از اپلیکیشنهای دیگر را مدیریت کند.
هر بلوک کد که نیازمند اجرا باشد، به صف کاری وارد میشود و سپس از سوی نخ اصلی سرویس میگیرد. از آنجا که نخ اصلی کار زیادی انجام میدهد، بهتر است کارهای طولانی روی نخهای دیگر قرار گیرد تا نخ UI از وظایف رندرینگ خود باز نماند. این نکته را همواره در نظر داشته باشید که نخ اصلی نباید کارهای طولانی انجام دهد که موجب مسدود شدن آن شود و در نهایت عدم پاسخگویی اپلیکیشن (ANR) را در پی داشته باشد. عملیات شبکه یا فراخوانی های پایگاه داده یا بارگذاری برخی کامپوننتها، نمونههایی از مواردی هستند که میتوانند منجر به مسدود شدن نخ اصلی شوند. این موارد به صورت همگام اجرا میشوند، یعنی UI تا زمانی که آن وظیفه کامل نشده است، کاملاً غیر پاسخگو میشود. برای اجتناب از بروز چنین موقعیتی، این وظایف به طور معمول در نخهای مجزایی اجرا میشوند که از مسدود شدن وظایف در زمان اجرای آن وظایف جلوگیری میکند. این بدان معنی است به صورت ناهمگام از UI اجرا میشوند. اندروید روشهای زیادی برای ایجاد و مدیریت نخها ارائه میکند و کتابخانههای شخص ثالث زیادی هم وجود دارند که موجب میشوند کار مدیریت نخها آسانتر شود. هر کلاس نخ بندی برای مقصود خاصی طراحی شده است، اما انتخاب کلاس مناسب برای نیازهای ما بسیار مهم است.
کلاس های Thread مختلف موجود به شرح زیر هستند:
AsyncTask: به گذاشتن یک کار روی نخ UI و برداشتن از روی آن کمک میکند.
HandlerThread: نخی برای callback-ها است.
ThreadPoolExecutor: بسیاری از کارهای موازی را اجرا میکند.
IntentService: به برداشتن اینتنتها از روی نخ UI کمک میکند.
مهم ترین خواص Thread در برنامه نویسی
Thread ها به تنهایی وجود ندارند و باید Process ای دربرگیرنده آن ها باشد.
Thread های هم والد «هم Process» از یک Memory مشترک استفاده می نمایند که آن نیز Memory اشغال شونده توسط Process آن ها می باشد.
Thread ها چه هم والد، چه غیر هم والد دارای Stack های جدا هستند.
با خاتمه یک Thread تأثیری به سایر Thread ها وارد نمی گردد.
Thread ها دیگر نمی توانند در برگیرنده Thread دیگری باشند.
چه زمانی از AsyncTask استفاده کنیم ؟
AsyncTask یک راه حل عالی برای کارهای کوتاه مدت است که به سرعت پایان مییابند و نیازمند به روز رسانی مکرر UI هستند. با این حال AsyncTask در مواردی که لازم باشد وظیفهای برای اجرا پس از چرخه عمر اکتیویتی/فرگمان به تأخیر بیفتد به درستی عمل نمیکند. لازم است اشاره کنیم که حتی چیزی به سادگی چرخش یک صفحه نیز ممکن است موجب تخریب اکتیویتی شود. به صورت پیشفرض، همه AsyncTask-ها روی یک نخ قرار میگیرند و به روش ترتیبی از یک صف پیام منفرد اجرا میشوند. اجرای همگام بر روی وظایف منفرد تأثیر میگذارد. اگر بخواهیم وظایف به صورت موازی اجرا شوند، میتوانیم از THREAD_POOL_EXECUTOR استفاده کنیم.