اذهب إلى المحتوى

السؤال

Recommended Posts

  • 1
نشر

هناك طريقتان متاحتان لعمل الثريد.
الطريقة الأولى هي انك تعمل وراثة لكلاس Thread.
يحتوي كلاس Thread على العديد من الدوال التي تسمح لنا بإجراء عمليات مختلفة على مؤشر الترابط. فئة الكائن تطبق الواجهة Runnable. تحتوي فئة مؤشر الترابط على المُنشئات التالية التي تُستخدم لإجراء عمليات متنوعة.

مثال:

// تنفيذ الواجهة عن طريق كلاس الثريد 
public class ThreadExample1 extends Thread {  
     // هذه الدالة من اجل تشغيل الثريد   
     public void run()  
     {    
        int a= 10;  
        int b=12;  
        int result = a+b;  
        System.out.println("Thread started running..");  
        System.out.println("Sum of two numbers is: "+ result);  
     }  
     public static void main( String args[] )  
     {  
      // هنا انشاء كائن للكلاس ثريد 
        ThreadExample1 t1 = new  ThreadExample1();  
        // هنا استدعاء دالة التنفيذ لتشغيل الثريد 
        t1.start();  // ويكون ناتج التنفيذ 22
     }  
}    

الطريقة الثانية هي تنفيذ واجهة التشغيل.

دعنا نأخذ مثالاً لفهم كيف يمكننا إنشاء وبدء وتشغيل Thread باستخدام الواجهة القابلة للتشغيل.

public class Main implements Runnable {
  public void run() { // نفس الدالة الموجودة في المثال السابق 
    System.out.println("This code is running in a thread");
  }
}


public class Main implements Runnable {
  public static void main(String[] args) {
    Main obj = new Main();
    Thread thread = new Thread(obj); // تمرير الكائن الى الثريد 
    thread.start();
    System.out.println("وهنا بداية الثريد");
  }
  public void run() {
    System.out.println("تشغيل الثريد");
  }
}

 

  • 0
نشر

يمكننا القيام بذلك من خلال تحقيق الواجهة Runnable أو من خلال الكلاس Thread الموجودان في الحزمة java.lang.
بعد ذلك نقوم بوضع الكود الذي نريد أن يتم تنفيذه ضمن خيط (Thread) منفصل بداخل الدالة ()run التي يتم تجاوزها من Thread/Runnable.
بعد ذلك نقوم باستدعاء الدالة()start من الكائن Thread لوضع الخيط (Thread) في حالة التشغيل.
مثال:
في المثال التالي قمنا بتعريف الكلاس Ex1 الذي يقوم بوراثة الكلاس Thread، وبداخل هذا الكلاس قمنا بتجاوز override الدالة ()run، و وضعنا بداخلها الكود الذي نريد أن يتم تنفيذه بشكل تفرعي (أي ضمن Thread منفصل) الكود هو طباعة رسالة بسيطة تمثل اسم ال thread، حيث تقوم الدالة getName بإرجاع اسم ال Thread الحالي.
بعد ذلك وضمن الدالة الرئيسية main قمنا بتعريف كائن من الكلاس Ex1، ثم استدعينا الدالة start التي ستقوم بتشغيل ال thread. وأخيراً نقوم بطباعة اسم ال Thread الحالي  (وهنا يكون main thread أي Thread الدالة الرئيسية).

// Thread نجعل الكلاس الحالي يرث الكلاس
public class Ex1 extends Thread { 
	// run الآن نضع الكود الذي نريده ضمن الدالة
    public void run() {
        System.out.println("name: " + getName());
    }
 
    public static void main(String[] args) {
		// الآن ضمن الدالة الرئيسية للبرنامج نقوم بإنشاء كائن من الكلاس السابق
        Ex1 t1 = new Ex1();
        // من خلال الكائن  start ثم نستدعي الدالة 
		t1.start();
        System.out.println("name: " + Thread.currentThread().getName());
    }
 
}

الخرج:

name: Thread-0
name: main

حيث أن Thread-0 هو اسم الخيط الذي قمنا بإنشائه و main هو اسم الخيط الذي يمثل الدالة الرئيسية (أي برنامج جافا).
الآن سيتبادر لأذهاننا السؤال التالي..
متى يتم إنهاء (متى يموت) الخيط Thread-0؟ الإجابة هي عندما تنتهي الدالة run من تنفيذ كامل الكود الموجود ضمنها.
أما بالنسبة للخيط main فينتهي عندما تنتهي الدالة الرئيسية main تنفيذ كامل التعليمات البرمجية التي تحتويها.
ملاحظة: في المثال السابق نلاحظ أنه تم تنفيذ الخيط Thread-0 أولاً ثم تم تنفيذ الخيط main، وهذا ليس بالضرورة أن يتم دائماً، فمثلاً لو جربنا تنفيذ الكود السابق أكثر من مرة سنلاحظ أن الخرج قد يختلف (أي قد يتم تنفيذ النيسب main أولاً مثلاً)، وليس بالضرورة أن يتم تنفيذ النيسب Thread-0 أولاً دوماً، حيث أن ترتيب تنفيذ النياسب هو أمر يتم تحديده في خوارزمية الجدولة للمعالج وليس من قبل المبرمج، إلا أنه يمكننا التحايل على هذا الأمر من خلال استخدام دوال تقوم بإجبار المعالج على تنفيذ الخيط الذي نريده بالترتيب الذي نحتاجه (سنتعرف على الأمر بعد قليل).
- يمكننا تحقيق نفس الأمر السابق من خلال الواجهة Runnable:

public class Ex2 implements Runnable {
    public void run() {
        System.out.println("name: " + Thread.currentThread().getName());
    }
    public static void main(String[] args) {
        Runnable th = new Ex2();
        Thread t2 = new Thread(th);
        t2.start();
        System.out.println("name: " + Thread.currentThread().getName());
    }
 
}

الآن كيف يمكننا ترتيب تنفيذ الخيوط (أي كيف يمكننا أن نجبر المعالج على تنفيذ خيط قبل الآخر)؟
يمكننا القيام بذلك من خلال الدالة join. على سبيل المثال لو أردنا أن يتم تنفيذ الخيط Thread-0 قبل الخيط main نقوم باستدعاء الدالة join من خلال الخيط Thread-0 بداخل الخيط main:

public class Ex2 implements Runnable {
    public void run() {
        System.out.println("name: " + Thread.currentThread().getName());
    }
    public static void main(String[] args) {
        Runnable th = new Ex2();
        Thread t2 = new Thread(th);
        t2.start();
		t2.join();
        System.out.println("name: " + Thread.currentThread().getName());
    }
 
}

مثال آخر:

public class ThreadJoinExample implements Runnable {
 
    public void run() {
        for (int i = 1; i <= 10; i++) {
            System.out.println("m" + i);
        }
    } 
    public static void main(String[] args) {
        Thread t1 = new Thread(new ThreadJoinExample());
        t1.start();
        t1.join();
        System.out.println(Thread.currentThread().getName());
    }
}

سيكون الخرج:

m1
m2
m3
m4
m5
m6
m7
m8
m9
m10
main

ملاحظة: الدالة join ترمي الاستثناء InterruptedException لذا يجب أن يتم التقاطه (في المثال السابق تجاهلت ذلك).

انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أجب على هذا السؤال...

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.

  • إعلانات

  • تابعنا على



×
×
  • أضف...