Java الكلاس ThreadGroup في جافا

مقدمة

الكلاس ThreadGroup يجعلك قادراً على التحكم بطريقة عمل مجموعة كائنات Thread دفعة واحدة.

فمثلاُ في حال قمت ببناء لعبة فيها إثنين Thread يعملان في نفس الوقت أثناء تشغيلها, الأول يعرض المدة المتبقية لإنتهاء المرحلة و الثاني يشغل أغنية حماسية يسمعها اللاعب أثناء اللعب. هنا بما أن الـ Thread الأول و الـ Thread الثاني يعملان و يتوقفان مع بعض, فإنه من الأفضل و الأسهل لك أن تضعهما في مجموعة واحدة للتحكم بهما دفعة واحدة بدل أن تقوم بتشغيل و إيقاف كل Thread منهما على حدة.

كائن الـ ThreadGroup الواحد يستطيع إحتواء عدة كائنات Thread, بالإضافة إلى أنه قادر على إحتواء كائنات ThreadGroup أيضاً.


بناؤه

public class ThreadGroup
extends Object
implements Thread.UncaughtExceptionHandler
	

التعامل مع الكلاس ThreadGroup

لجعل كائن الـ Thread ينتمي لكائن ThreadGroup محدد ( أي لمجموعة محددة ), عليك ربطه به ككائن نوعه Runnable.


خطوات بناء كلاس يطبق الإنترفيس Runnable

الكلاس الذي يطبق الإنترفيس Runnable عليه القيام بالخطوات التالية:

  1. تطبيق الإنترفيس Runnable, أي أن يفعل له implements.
  2. كتابة محتوى الدالة run(), أي أن يفعل لها Override و يضع فيها جميع الأوامر التي يريدها أن تتنفذ عند تشغيل كائن الـ Thread.

مثال

MyRunnable.java
public class MyRunnable implements Runnable {

    @Override
    public void run(){
        // Thread من كائن من الكلاس start() هنا تضع الأوامر التي تريد تنفيذها عند إستدعاء الدالة
    }

}
		


خطوات إنشاء كائن من الكلاس ThreadGroup لإدارة عمل مجموعة كائنات من الكلاس Thread

لإنشاء كائن من الكلاس الذي يطبق الإنترفيس Runnable و ضمه إلى مجموعة محددة, عليك إتباع الخطوات التالية:

  1. إنشاء كائن من الكلاس ThreadGroup, أي إنشاء مجموعة جديدة.
  2. إنشاء كائن من الكلاس الذي يرث من الإنترفيس Runnable.
  3. إنشاء كائن من الكلاس Thread, و تمرير كائن الـ Runnable و كائن الـ ThreadGroup كـ Arguments له.
  4. تشغيل كائن الـ Thread بواسطة الدالة start().
  5. بعدها يمكنك التعامل مع الكائن ThreadGroup للتحكم بجميع كائنات الـ Thread التي تنتمي إليه.

مثال

MainThreadGroup.java
public class MainThreadGroup {

    public static void main(Strigns[] args)){

        ThreadGroup tg = new ThreadGroup("tg group");     // tg group و قمنا بتسمية هذه المجموعة tg إسمه ThreadGroup هنا قمنا بإنشاء كائن من الكلاس

        MyRunnable mr = new MyRunnable();                 // MyRunnable هنا قمنا بإنشاء كائن من الكلاس الذي يطبق الإنترفيس

        Thread t = new Thread(tg, mr);                    // tg و بالمجموعة mr و ربطه بالكائن Thread هنا قمنا بإنشاء كائن من الكلاس

        t.start();                                        // start() بواسطة الدالة run() هنا قمنا بتشغيل أوامر الدالة

    }

} 
		

كونستركتورات الكلاس ThreadGroup

في الجدول التالي ذكرنا جميع كونستركتورات الكلاس ThreadGroup.

الكونستركتور مع تعريفه
public ThreadGroup(String name) ينشئ كائن نوعه ThreadGroup مع تحديد إسمه.
الأب لهذا الكائن يكون الـ Thread الحالي الذي قام بإنشائه.
يرمي الإستثناء SecurityException في حال كان الـ Thread الحالي لا يملك صلاحية إنشاء كائن ThreadGroup.
public ThreadGroup(ThreadGroup group, String name) ينشئ كائن نوعه ThreadGroup و يضعه ضمن مجموعة محددة, مع تحديد إسمه.

باراميترات
  • group عبارة عن كائن نوعه ThreadGroup يمثل المجموعة التي سيتم وضع هذا الكائن فيها.
  • name عبارة عن إسم يتم إعطاءه لكائن الـ ThreadGroup الذي سيتم إنشاءه و وضعه ضمن المجموعة المذكورة.

يرمي الإستثناء SecurityException في حال كان كائن الـ Thread الحالي لا يملك صلاحية إنشاء كائن ThreadGroup جديد بداخل المجموعة المشار إليها.

دوال الكلاس ThreadGroup

الجدول التالي يحتوي على دوال الكلاس ThreadGroup.

الدالة مع تعريفها
public final String getName() ترجع إسم كائن الـ ThreadGroup.
public String toString() ترجع نص يمثل معلومات كائن الـ ThreadGroup الذي قام باستدعائها. المعلومات عبارة عن ( Priority - Name ).
  • Name: هو إسم كائن الـ ThreadGroup.
  • Priority: هو أولية التفيذ المعطاة لكائن الـ ThreadGroup.
public final ThreadGroup getParent() ترجع كائن نوعه ThreadGroup يمثل الـ ThreadGroup الأب الذي تم فيه إنشاء هذا الكائن أو المجموعة التي ينتمي لها كائن ThreadGroup الذي قام باستدعائها.
public int activeCount() تستخدم لمعرفة عدد الـ threads الذين يعملون ضمن كائن الـ ThreadGroup لحظة استدعائها.
تستخدم فقط في حالة الـ Debugging.
public final void setDaemon(boolean on) تستخدم لتحويل كائن الـ ThreadGroup الذي قام باستدعائها إلى Daemon ThreadGroup.
الـ Daemon ThreadGroup يستدعي الدالة destroy() عندما لا يبقى أي Thread في حالة التنفيذ.
في حال قمت بتمرير القيمة true لها كـ Argument, سيتم معاملة كائن الـ ThreadGroup كــ Daemon ThreadGroup.
غير ذلك سيتم إعتباره كائن ThreadGroup عادي.

ترمي الإستثناء IllegalArgumentException في حال كان كائن الـ ThreadGroup شغالا أثناء استدعاءها.
و ترمي الإستثناء SecurityException في حال كان كائن الـ ThreadGroup الحالي لا يملك صلاحية تغييرها.
public final boolean isDaemon() تستخدم لمعرفة إذا كان كائن الـ ThreadGroup الذي قام باستدعائها هو Daemon ThreadGroup أم لا.
ترجع true إذا كان كذلك, غير ذلك ترجع false.
public final void suspend() توقف تنفيذ أوامر جميع كائنات الـ Thread و الـ ThreadGroup التابعة للكائن ThreadGroup الذي قام باستدعائها لمدة غير محددة, بحيث لا يمكنهم العودة للعمل من جديد إلا إذا قام باستدعاء الدالة resume() بعدها.
ترمي الإستثناء SecurityException في حال كان كائن الـ ThreadGroup لا يملك صلاحية التعديل على كائنات الـ Thread أو الـ ThreadGroup التابعة له و المتوقفة عن العمل.
public final void resume() تكمل تنفيذ أوامر جميع كائنات الـ Thread و الـ ThreadGroup التابعة للكائن ThreadGroup بعد أن كان قد قام بإيقاف تنفيذهم في حال قام بإيقافهم بواسطة الدالة suspend().
ترمي الإستثناء SecurityException في حال كان كائن الـ ThreadGroup لا يملك صلاحية التعديل على كائنات الـ Thread أو الـ ThreadGroup التابعة له و المتوقفة عن العمل.
public final void stop() توقف جميع كائنات الـ Thread و الـ ThreadGroup التابعة للكائنThreadGroup الذي قام باستدعائها, بحيث لا يمكنهم العودة للعمل من جديد.
ترمي الإستثناء SecurityException في حال كان كائن الـ ThreadGroup لا يملك صلاحية التعديل على كائنات الـ Thread أو الـ ThreadGroup التابعة له و المتوقفة عن العمل.
public final void interrupt() ترسل إشارة إلى الـ JVM لمقاطعة عمل جميع كائنات الـ Thread و الـ ThreadGroup التابعة للكائن ThreadGroup الذي قام باستدعائها.
في حال كان كائن الـ ThreadGroup غير شغال بعد لا تؤثر عليه أيضاً.

ترمي الإستثناء SecurityException في حال كان كائن الـ ThreadGroup الحالي لا يملك صلاحية التعديل على كائنات الـ Thread و الـ ThreadGroup التابعة له.

مثال شامل

في المثال التالي قمنا بإنشاء كلاس إسمه MyRunnable يطبق الإنترفيس Runnable.
بعدها فعلنا Override للدالة run() لجعلها تطبع إسم كائن الـ Thread الذي قام باستدعائها بدون أن تتوقف.

ثم قمنا بإنشاء كلاس إسمه Main لتجربة إنشاء ThreadGroup و وضع كائنات من الـ Thread فيه.


MyRunnable.java
public class MyRunnable implements Runnable {
 
    @Override
    public void run() {
        // true ترجع isInterrupted() طالما أن الدالة
        while(!Thread.currentThread().isInterrupted())
        {
            // الذي يتم تنفيذ محتواه في الوقت الحالي Thread سيتم طباعة إسم كائن الـ
            System.out.println(Thread.currentThread().getName());
        }
    }
 
}
		

Main.java
public class Main {
 
    public static void main(String[] args) {
 
        // tg إسمه ThreadGroup هنا قمنا بإنشاء كائن من الكلاس
        ThreadGroup tg = new ThreadGroup("tg group");
 
        // tg ثم جعلناه ينتمي لمجموعة الكائن t1 إسمه Thread و ربطناه بكائن من الكلاس MyRunnable هنا قمنا بإنشاء كائن من الكلاس
        Thread t1 = new Thread(tg, new MyRunnable(), "Thread 1");
 
        // tg ثم جعلناه ينتمي لمجموعة الكائن t2 إسمه Thread و ربطناه بكائن من الكلاس MyRunnable هنا قمنا بإنشاء كائن من الكلاس
        Thread t2 = new Thread(tg, new MyRunnable(), "Thread 2");
 
        // t1 هنا قمنا بتشغيل الكائن
        t1.start();
 
        // t2 هنا قمنا بتشغيل الكائن
        t2.start();
 
        // يعدها سيتم إيقاف تنفيذ باقي الأوامر الموجودة في البرنامج مدة ثانية واحدة
        try {
            Thread.sleep(1000);
        }
        catch(Exception e) {
            System.out.println(e.getMessage());
        }
 
        // tg تابع للكائن Thread بعد إنقضاء الثانية سيتم إيقاف تنفيذ كل
        tg.interrupt();
 
        // في الأخير سيتم عرض الجملة التالية
        System.out.println("All Threads in 'tg group' are interrupted!");
 
    }
 
}
		

سنحصل على نتيجة تشبه النتيجة التالية عند التشغيل.

Thread 2
Thread 1
Thread 1
Thread 2
Thread 2
Thread 2
Thread 1
Thread 2
Thread 2
Thread 2
Thread 2
Thread 1
Thread 1
Thread 1
All Threads in 'tg group' are interrupted!
		

الدورات

أدوات مساعدة

أقسام الموقع

دورات
مقالات كتب مشاريع أسئلة