مثال على خيوط جافا

مرحبًا بك في مثال حول خيوط جافا. العملية و الخيط هما وحدتان أساسيتان للتنفيذ. برمجة التزامن تهتم أكثر بخيوط جافا.

العملية

A process is a self contained execution environment and it can be seen as a program or application. However a program itself contains multiple processes inside it. Java runtime environment runs as a single process which contains different classes and programs as processes.

الخيط

يمكن تسمية الخيط بـعملية خفيفة. يحتاج الخيط إلى موارد أقل للإنشاء ويوجد في العملية، ويشترك الخيط في موارد العملية.

مثال على خيط جافا

كل تطبيق جافا لديه على الأقل خيط واحد – الخيط الرئيسي. على الرغم من وجود العديد من الخيوط الجافا الأخرى التي تعمل في الخلفية مثل إدارة الذاكرة وإدارة النظام ومعالجة الإشارة وما إلى ذلك. ولكن من وجهة نظر التطبيق – الخيط الرئيسي هو أول خيط جافا ويمكننا إنشاء العديد من الخيوط منه. يشير التعدد إلى تنفيذ اثنين أو أكثر من الخيوط بشكل متزامن في برنامج واحد. يمكن أن ينفذ معالج النواة الواحد للكمبيوتر فقط خيط واحد في وقت واحد و تقسيم الوقت هو ميزة نظام التشغيل لمشاركة وقت المعالج بين عمليات وخيوط مختلفة.

فوائد خيوط جافا

  1. خيوط جافا خفيفة الوزن بالمقارنة مع العمليات، فهي تستغرق وقتًا وموارد أقل لإنشاء خيط.
  2. تشترك الخيوط في بيانات وشفرة عملية الأصل.
  3. عملية التبديل بين الخيوط عادة ما تكون أقل تكلفة من عملية التبديل بين العمليات.
  4. التواصل بين الخيوط سهل نسبيًا مقارنةً بالتواصل بين العمليات.

توفر جافا طريقتين لإنشاء خيط برمجيًا.

  1. تنفيذ واجهة java.lang.Runnable.
  2. تمديد فئة java.lang.Thread.

مثال على خيط جافا – تنفيذ واجهة Runnable

لجعل فئة قابلة للتشغيل، يمكننا تنفيذ واجهة java.lang.Runnable وتوفير التنفيذ في طريقة public void run(). لاستخدام هذه الفئة كـ Thread، نحتاج إلى إنشاء كائن Thread عن طريق تمرير كائن هذه الفئة القابلة للتشغيل ثم استدعاء طريقة start() لتنفيذ طريقة run() في خيط منفصل. فيما يلي مثال على خيط جافا عن طريق تنفيذ واجهة Runnable.

package com.journaldev.threads;

public class HeavyWorkRunnable implements Runnable {

    @Override
    public void run() {
        System.out.println("Doing heavy processing - START "+Thread.currentThread().getName());
        try {
            Thread.sleep(1000);
            //الحصول على اتصال قاعدة البيانات، حذف البيانات غير المستخدمة من قاعدة البيانات
            doDBProcessing();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("Doing heavy processing - END "+Thread.currentThread().getName());
    }

    private void doDBProcessing() throws InterruptedException {
        Thread.sleep(5000);
    }

}

مثال على خيط جافا – تمديد فئة Thread

يمكننا تمديد فئة java.lang.Thread لإنشاء فئة خيط جافا خاصة بنا وتجاوز طريقة run(). ثم يمكننا إنشاء كائنها واستدعاء طريقة start() لتنفيذ طريقة تشغيل الخيط الجافا المخصصة لدينا. فيما يلي مثال بسيط على خيط جافا يوضح كيفية تمديد فئة Thread.

package com.journaldev.threads;

public class MyThread extends Thread {

    public MyThread(String name) {
        super(name);
    }

    @Override
    public void run() {
        System.out.println("MyThread - START "+Thread.currentThread().getName());
        try {
            Thread.sleep(1000);
            //الحصول على اتصال قاعدة البيانات، حذف البيانات غير المستخدمة من قاعدة البيانات
            doDBProcessing();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("MyThread - END "+Thread.currentThread().getName());
    }

    private void doDBProcessing() throws InterruptedException {
        Thread.sleep(5000);
    }
    
}

فيما يلي برنامج اختبار يوضح كيفية إنشاء خيط جافا وتنفيذه.

package com.journaldev.threads;

public class ThreadRunExample {

    public static void main(String[] args){
        Thread t1 = new Thread(new HeavyWorkRunnable(), "t1");
        Thread t2 = new Thread(new HeavyWorkRunnable(), "t2");
        System.out.println("Starting Runnable threads");
        t1.start();
        t2.start();
        System.out.println("Runnable Threads has been started");
        Thread t3 = new MyThread("t3");
        Thread t4 = new MyThread("t4");
        System.out.println("Starting MyThreads");
        t3.start();
        t4.start();
        System.out.println("MyThreads has been started");
        
    }
}

إن الناتج من المثال أعلاه لبرنامج خيط جافا هو:

Starting Runnable threads
Runnable Threads has been started
Doing heavy processing - START t1
Doing heavy processing - START t2
Starting MyThreads
MyThread - START Thread-0
MyThreads has been started
MyThread - START Thread-1
Doing heavy processing - END t2
MyThread - END Thread-1
MyThread - END Thread-0
Doing heavy processing - END t1

بمجرد بدء أي خيط، يعتمد تنفيذه على تنفيذ نظام التشغيل للتقسيم الزمني ولا يمكننا التحكم في تنفيذها. ومع ذلك، يمكننا تعيين أولوية الخيوط ولكن حتى ذلك الحين لا يضمن أن الخيط ذو الأولوية الأعلى سيتم تنفيذه أولاً. قم بتشغيل البرنامج أعلاه عدة مرات وسترى أنه لا يوجد نمط محدد لبدء وانتهاء الخيوط.

Runnable vs Thread

إذا قدمت صنفك مزيدًا من الوظائف بدلاً من العمل فقط كـ Thread، يجب عليك تنفيذ واجهة Runnable لتوفير طريقة لتشغيله كـ Thread. إذا كان هدف صنفك فقط هو التشغيل كـ Thread، يمكنك تمديد صنف Thread. يُفضل تنفيذ Runnable لأن لغة جافا تدعم تنفيذ العديد من الواجهات. إذا قمت بتمديد صنف Thread، فلن يمكنك تمديد أي صنوف أخرى. نصيحة: كما لاحظتم أن الخيط لا يعيد أي قيمة ولكن ماذا لو أردنا أن يقوم الخيط ببعض المعالجة ومن ثم يعيد النتيجة إلى برنامج العميل الخاص بنا، شاهدوا Java Callable Future. تحديث: بدءًا من جافا 8، تصبح واجهة Runnable واجهة وظيفية ويمكننا استخدام تعبيرات لامبدا لتوفير تنفيذها بدلاً من استخدام فئة مجهولة. لمزيد من التفاصيل، تحققوا من واجهات جافا الوظيفية في جافا 8.

Source:
https://www.digitalocean.com/community/tutorials/java-thread-example