آشنایی با Multi threading در جاوا

در بسیاری از نرم افزارها نیازمند اجرای چند Task به موازات هم هستیم. قابلیت multi tasking در سیستم عاملها مختلف برای این تعبیه شده که چندین وظیفه توسط منابع محدودی مثل cpu به صورت موازی انجام شوند و در واقع زمان منابع موجود بین وظایف مختلف تقسیم میشود.

سیستم عامل برای اجرا دو پردازش سنگین، منابعی مثل Cpu را با فاصله زمانی کوتاهی بین Process ها سوئیج میکند. این عمل به ویژه در پردازشهایی که منابعی دیگر جز CPU را درگیر میکنند کاربردی است تا دیگر پردازشها را معطل نکنند.

قبل از هر چیزی باید دو واژه Process و Thread را تعریف کنیم. هر دو این واژه ها با مفهوم Multi tasking گره خورده اند. Multi Tasking یا چند وظیفگی به دوشکل پیاده سازی میشود :

1- Multi Processing (چند پردازشی)

2- Multi Threading (چند نخی)

روش چند پردازشی

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

معمولا تخصیص منابع و سوئیچ بین Process ها در سطح سیستم عامل انجام میشود و سوئیچ و ارتباط بین Process ها هزینه بر است. Process ها سنگین وزن هستند و خود میتوانند از چندین Thread تشکل شوند.

روش چند نخی

در این روش Thread هایی در یک فضای حافظه مشترک اجرا میشوند و در دل یک Process هستند (داخل یک برنامه هستند) . Thread ها بسیار سبک هستند و ارتباط بین آنها به سادگی ایجاد میشود .همچنین سوئیچ بین Thread ها با سرعت بیشتری انجام میشود.

Process Vs Thread

چرخه حیات نخ (Thread States)

یک Thread دارای چرخه حیاتی است که از زمان تولد تا مرگ وضعیتهای مختلفی را به خود میبیند. وضعیتهای Thread در طول چرخه حیاتش به شرح زیر است :

  1. New
  2. Runnable
  3. Running
  4. Non-Runnable (Blocked)
  5. Terminated


1- جدید (New) : زمانی که یک شیء از نوع Thread ساخته میشود در این وضعیت قرار میگیرد

2- قابل اجرا (Runnable) : زمانی که Thread آغاز به کار میکند در این وضعیت قرارمیگیرد تا نوبت پردازشش فرا برسد. با فراخوانی متد start این وضعیت برای Thread فعال میشود.

3- درحال اجرا (Running) : زمانی که نوبت اجرا به Thread میرسد و Cpu را در اختیار میگیرد در وضعیت درحال اجرا قرار میگیرد.

4- متوقف (Block) : زمانی که وقفه ای در اجرا Thread ایجاد شود در این وضعیت قرار میگیرد و پس از پایان وقفه وضعیت به Runnable تغییر میکند تا در نوبت اجرا قرارگیرد. (در این وضعیت Thread خاتمه نیافته اما واجد شرایط اجرا شدن نیست)

5- خاتمه یافته (Terminated) : زمانی که عملکرد Thread خاتمه میابد در این وضعیت قرار میگیرد (به عبارتی میمیرد)

پیاده سازی Thread در جاوا

دو روش برای پیاده سازی Thread در جاوا وجود دارد :

1- ارث بری از کلاس Thread

2- پیاده سازی اینترفیس Runnable

نحوه پیاده سازی اول

  1. class Multi extends Thread{
  2. public void run(){
  3. System.out.println("thread is running...");
  4. }
  5. public static void main(String args[]){
  6. Multi t1=new Multi();
  7. t1.start();
  8. }
  9. }

در این مثال با ارث بری از کلاس Thread پیاده سازی انجام شده. بدنه اصلی Thread باید در متد run نوشته شود و برای اجرای Thread هم از متد start استفاده میشود. با اجرای این برنامه یک Thread جدید ساخته شده و محتوای متد run اجرا میشود.

نحوه پیاده سازی دوم

  1. class Multi3 implements Runnable{
  2. public void run(){
  3. System.out.println("thread is running...");
  4. }
  5. public static void main(String args[]){
  6. Multi3 m1=new Multi3();
  7. Thread t1 =new Thread(m1);
  8. t1.start();
  9. }
  10. }

در این روش اینترفیس Runnable باید پیاده سازی شود و مانند مثال قبل متد run نوشته شود. برای اجرا باید یک شیء از کلاس Thread ساخته شود و شیء Runnable را به متد سازنده آن داده و با متد start آنرا اجرا کنیم.