چند نخی یا Multi Threading در جاوا (بخش 1)

بنام خدا .

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

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

چند نخی یا MultiThreding  در واقع میتونه به چند وظیفگی یا تقسیم  پردازش یا برنامه به بخشهای مجزا  منجر بشه  که بسایر روش مفید و موثری هست.  با این سبک برنامه نویسی میتونیم چند پردازش رو بصورت همزامان اجرا کنیم. مثلا از یک  طرف  پیغامهای جدید رو در هر لحظه چک کنیم و همزمان به سایر کارهای برنامه بپردازیم.

یک ترید میتونه در حالتها مختلف باشه یعنی میتونه وضعیت های مختلفی داشته باشه  که در شکل زیر این حالات رو میبینیم.

 

New : وقتی برای اولین بار یک Thread رو ایجاد میکنیم این وضعیت پیش میاد .

Runnable :  بعد از ایجاد یک نخ یا Thread به حالتی میره که میتونه اجرا بشه و اگر اجرا شد در وضعیت Running قرار میگیره.

Wating  : گاهی به دلایل مختلف ازجمله انتظار برای پایان تریدی دیگه (استفاده از منابع مشترک) یک نخ میتونه به حالت انتظار بره که بعد از مساعد شدن اوضا میتونه به Runnable برگرده.

Time Wating  : گاهی ما یک دوره زمانی برای اجرای ترید میذاریم مثلا میگیم هر دو ثانیه یک بار اجرا بشه . انتظاری رو که در اثر این دوره های زمانی یا Interval ها بوجود میاد رو انتظار زمانی میگیم

Dead : وقتی به هر دلیلی عمدی یا سهوی یا هر اتفاق دیگه ای یک نخ اجراش پایان یافت یا کاملا متوقف شد این وضعیت پیش میاد.

نکته : Thread ها در جاوا دارای الویت هستن. یعنی  هرکدوم دارای شماره ای هست که  نشان دهنده اولویت اجرایش هست . این شماره از 1 شروع میشه تا 10 و تریدی که شماره بالا داشته باشه اولویت اجرایش بالاتر هست. بطور پیشفرض جاوا  شماره 5 رو برای ترید در نظر میگیره.

از دو طریق میشه یک نخ رو توی جاوا ایجاد کرد :

1- ارث بری از اینترفیس Runnable

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

Runnable :

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

در برنامه زیر یک کلاس از نوع Runnable میسازیم :

//تعریف یک کلاس از نوع قابل اجرا یا Runnable
class RunnableDemo implements Runnable {
    private Thread t;
    private String threadName;

    RunnableDemo( String name){
    //تعیین نام نخ در هنگام ایجاد کلاس درمتد سازنده
    threadName = name;
    System.out.println("Creating " + threadName );
 }

    //در این بلاک آنچه قرار است در هنگام اجرای ترید انجام شود رو مینویسیم
    public void run() {
        System.out.println("Running " + threadName );
    try {
        for(int i = 4; i > 0; i--) {
        System.out.println("Thread: " + threadName + ", " + i);
        // Let the thread sleep for a while.
        //ایجاد 50 میلی ثانیه انتظار 
        Thread.sleep(50);
        }
    } catch (InterruptedException e) {
    System.out.println("Thread " + threadName + " interrupted.");
    }
    System.out.println("Thread " + threadName + " exiting.");
}

    // متد شروع اجرای ترید که شامل تعریف شی و شروع اون هست
    public void start ()
    {
        System.out.println("Starting " + threadName );
        if (t == null)
        { 
            //تعریف
            t = new Thread (this, threadName);
            //شروع اجرا
            t.start ();
    }
}

}
//کلاس اصلی برنامه برای اجرای کلاس ترید
public class TestThread {
    public static void main(String args[]) {

        //تعریف یک نمونه شی از کلاس ترید ما . اجرای اون
        RunnableDemo R1 = new RunnableDemo( "Thread-1");
        R1.start();

        RunnableDemo R2 = new RunnableDemo( "Thread-2");
        R2.start();
} 
} 

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

 Creating Thread-1
Starting Thread-1
Creating Thread-2
Starting Thread-2
Running Thread-1
Thread: Thread-1, 4
Running Thread-2
Thread: Thread-2, 4
Thread: Thread-1, 3
Thread: Thread-2, 3
Thread: Thread-1, 2
Thread: Thread-2, 2
Thread: Thread-1, 1
Thread: Thread-2, 1
Thread Thread-1 exiting.
Thread Thread-2 exiting.. 

Thread :

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

  //کلاس ترید با ارث بری از از کلاس اصلی ترید
class ThreadDemo extends Thread {
    private Thread t;
    private String threadName;

    //سازنده کلاس 
    ThreadDemo( String name){
        // تعیین نام نخ
        threadName = name;
        System.out.println("Creating " + threadName );
    }
    //متدی که موقع اجرای ترید اجرا میشه
    public void run() {
        System.out.println("Running " + threadName );
        try {
            for(int i = 4; i > 0; i--) {
                 System.out.println("Thread: " + threadName + ", " + i);
                 // Let the thread sleep for a while.
                 Thread.sleep(50);
            }
        } catch (InterruptedException e) {
        System.out.println("Thread " + threadName + " interrupted.");
    }
    System.out.println("Thread " + threadName + " exiting.");
    }

    // متد شروع اجرای ترید
    public void start ()
    {
        System.out.println("Starting " + threadName );
        if (t == null)
        {
            //ایجاد ترید
            t = new Thread (this, threadName);
            // شروع اجرا
            t.start ();
        }
    }

    }
    //کلاس اصلی برنامه برای اجرای ترید    
    public class TestThread {
        public static void main(String args[]) {

            ThreadDemo T1= new ThreadDemo( "Thread-1");
            T1.start();

            ThreadDemo T2 = new ThreadDemo( "Thread-2");
            T2.start();
    } 
}

نتیجه اجرا این کدهم میبینیم :

 Creating Thread-1
Starting Thread-1
Creating Thread-2
Starting Thread-2
Running Thread-1
Thread: Thread-1, 4
Running Thread-2
Thread: Thread-2, 4
Thread: Thread-1, 3
Thread: Thread-2, 3
Thread: Thread-1, 2
Thread: Thread-2, 2
Thread: Thread-1, 1
Thread: Thread-2, 1
Thread Thread-1 exiting.
Thread Thread-2 exiting. 

در جلسه بعد یک سری نکات رو در مورد ترید ارائه خواهیم داد

تا جلسه بعد در پناه حق


فایلهای ضمیمه
توجه! هیچ فایل ضمیمه ای برای این مطلب یافت نشد

نظرات شما نظر جدید