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

السؤال

Recommended Posts

  • 2
نشر

إن الفرق بين الطريقتين هو كالتالي:
أولاً: عن طريق تطبيق الواجهة Runnable Interface:

public class DemoRunnable implements Runnable {
    public void run() {
        //نضع هنا الكود الخاص بالعملية
    }
}

ثانياً: عن طريق استخدام الصف Thread:

public class DemoThread extends Thread {
    public DemoThread() {
        super("DemoThread");
    }
    public void run() {
        //نضع هنا الكود الخاص بالعملية
    }
}

وإن كلا الطريقتين متشابهتين ولا يوجد طريقة جيدة وأخرى سيئة، وأيضاً يوجد العديد من النقاشات حول استخدامات كل منها، ولكن من أهم الفروقات أو النقاط التي يجب عليك الانتباه لها لاختيار الطريقة المناسبة هي:
1- في استخدام Runnable أنت لا تخصص حقًا سلوك المسالك أو تعدلها. أنت فقط تعطي المسلك شيئًا لتشغيله. هذا يعني أن الترتيب في الكود سيكون أفضل.

2- لغة جافا تدعم فقط الوراثة وحيدة الدرجة، لذلك لا يمكنك إنشاء extend لأكثر من صف.

3- إن إنشاء واجهة تعطي interface تسمح لك بفصل المكونات عن بعضها ضمن الكود، وبذلك يصبح الكود الخاص بك أكثر مرونة ويمكنك ذلك من فصله عن العمليات المستخدمة ضمن المسلك thread.

4- في استخدام Runnable تجعل الصف الذي يقوم باستدعائها أكثر مرونة، أما إذا استخدمت Thread فإن الحدث الذي سيقوم به سيبقى دوماً ضمن الـ thread، أما في الحالة الأخرى أي Runnable فليس من الضرورة أن يبقى ضمن المسلك thread حيث يمكنك أيضاً تمرير البيانات إلى خدمات وصفوف أخرى.

5- وأخيراً، في حال قررت استخدام Thread فيجب عليك الانتباه إلى وجود خطأ بسيط Bug في نسخ JDK 4 أو الأقدم يتعلّق بالتوقيت بين بناء المسلك contruction و بدء عمله start، حيث قامت شركة Sun بإصلاح الخطأ بدءً من نسخ Java 1.5 ولذلك يجب عليك الانتباه للنسخة التي تقوم باستخدامها من جافا.

وإذا نظرنا إلى جميع النقاط السابقة يمكن أن نلاحظ أن استخدام runnable مناسب أكثر لمعظم الحالات. ولكن هذا لا يعني عدم استخدام الصف Thread فكل مبرمج يفضّل الطريقة التي تناسب عمله ويرتاح بالعمل فيها.

  • 1
نشر

سأضيف معلومة مهمة جداً: عند إنشاء Thread بإستخدام Runnable فإنه يمكن تشارك الـObject لكل الـthreads، عكس الطريقة الثانية التي تنشئ Object منفصل لكل thread.
سأترك لك مثال موضح بالتعليقات لتفهم الأمر بشكل أفضل:

 class MyImplementedThread implements Runnable{ // الطريقة الأولى
    public int counter = 0;
    @Override
    public void run(){
        counter++; // يتم زيادة العداد في كل مرة يتم تشغيل
      				//thread
        System.out.println("implemented: "+counter);
    }
}
class MyThread extends Thread{ // الطريقة الثانية
    public int counter = 0;
    @Override
    public void run(){
        counter++;
        System.out.println("MyTheread: "+counter);
    } 
}
public class Main{
     public static void main(String []args){
         //الطريقة الأولى
        MyImplementedThread myImplementedThread = new MyImplementedThread();
       /*
       ننشئ الكائن الذي ستشترك به كل الـ
       threads
       التي ستتبع الطريقة الأولى
       */
        Thread implemented1 = new Thread(myImplementedThread);
       /*
       نعرف 
       thread
       جديدة مع ارفاق الكائن الخاص بالطريقة الأولى
       */
        implemented1.start(); //  نبدأ عمل الـ
       						//thread		
        try{
            Thread.sleep(1000);
          /*
           نقوم بإيقاف تشغيل مؤقت لمدة ثانية واحدة قبل متابعة إنشاءالـ
           threads
           الأخرى
          */
        }
        catch(Exception e){
            System.out.println(e.getMessage());
        }
        Thread implemented2 = new Thread(myImplementedThread);
        implemented2.start();
        
        try{
            Thread.sleep(1000);
        }
        catch(Exception e){
            System.out.println(e.getMessage());
        }
        
        
        Thread implemented3 = new Thread(myImplementedThread);
        implemented3.start();
        
        try{
            Thread.sleep(1000);
        }
        catch(Exception e){
            System.out.println(e.getMessage());
        }
        //----------------------
       //الطريقة الثانية
        MyThread myThread1 = new MyThread();
        myThread1.start();
        /*
        ننشئ 
        thread
        منفصلة في كل مرة
        */
        try{
            Thread.sleep(1000);
        }
        catch(Exception e){
            System.out.println(e.getMessage());
        }
        MyThread myThread2 = new MyThread();
        myThread2.start();
        
        try{
            Thread.sleep(1000);
        }
        catch(Exception e){
            System.out.println(e.getMessage());
        }
        
        MyThread myThread3 = new MyThread();
        myThread3.start();
        
        try{
            Thread.sleep(1000);
        }
        catch(Exception e){
            System.out.println(e.getMessage());
        }  
     }
}

لاحظ ناتج تنفيذ البرنامج:
1.thumb.png.9bc2f761350e2fa1d3e654c90e378196.png

وهذا يدل على التشارك في الـObject في الطريقة الأولى حيث تم زيادة الـcounter بواحد من قبل كل thread
بينما في الطريقة الثانية كل thread كان لها object خاص بها وبالتالي ظهر الرقم واحد بدون أي زيادة.

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

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

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

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   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.

  • إعلانات

  • تابعنا على



×
×
  • أضف...