تعدد مؤشرات الترابط في جافا: كيف تبدأ مع المواضيع

ما هو الموضوع؟

الخيط هو عملية خفيفة الوزن. يمكن أن تحتوي أي عملية على مؤشرات ترابط متعددة تعمل فيها.

على سبيل المثال ، في متصفح الويب ، يمكن أن يكون لدينا مؤشر ترابط واحد يقوم بتحميل واجهة المستخدم وخيط آخر يقوم بالفعل باسترداد جميع البيانات التي يجب عرضها في تلك الواجهة.

ما هو MultiThreading؟

يتيح لنا Multithreading تشغيل سلاسل رسائل متعددة في نفس الوقت.

على سبيل المثال في متصفح الويب ، يمكن أن يكون لدينا مؤشر ترابط واحد يتعامل مع واجهة المستخدم ، وبالتوازي يمكن أن يكون لدينا مؤشر ترابط آخر يقوم بجلب البيانات المراد عرضها.

لذا فإن تعدد مؤشرات الترابط يحسن استجابة النظام.

ما هو التزامن؟

يتيح لنا التزامن في سياق الخيوط تشغيل سلاسل رسائل متعددة في نفس الوقت.

لكن هل الخيوط تعمل حقًا في نفس الوقت؟

أنظمة أحادية النواة

برنامج جدولة الخيط الذي يوفره JVM يقرر أي خيط يتم تشغيله في أي وقت. يعطي المجدول شريحة زمنية صغيرة لكل مؤشر ترابط.

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

أنظمة متعددة النوى

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

على سبيل المثال ، إذا كان لدينا نظام ثنائي النواة ، فيمكننا تشغيل خيطين في نفس الوقت بالضبط. سيتم تشغيل الخيط الأول في النواة الأولى ، وسيعمل الخيط الثاني في النواة الثانية.

لماذا هو مطلوب تعدد؟

يتيح لنا تعدد مؤشرات الترابط تحسين استجابة النظام.

على سبيل المثال ، في متصفح الويب ، إذا تم تشغيل كل شيء في سلسلة رسائل واحدة ، فلن يستجيب النظام تمامًا عندما يتم جلب البيانات لعرضها. على سبيل المثال ، إذا استغرق جلب البيانات 10 ثوانٍ ، فلن نتمكن في تلك العشر ثوانٍ من القيام بأي شيء آخر في متصفح الويب مثل فتح علامات تبويب جديدة ، أو حتى إغلاق متصفح الويب.

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

كيفية كتابة البرامج متعددة مؤشرات الترابط في جافا

يمكننا إنشاء سلاسل في Java باستخدام ما يلي

  • تمديد فئة الموضوع
  • تنفيذ واجهة التشغيل
  • تنفيذ واجهة الاستدعاء
  • باستخدام إطار عمل المنفذ جنبًا إلى جنب مع المهام القابلة للتشغيل والاستدعاء

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

تمديد فئة الموضوع

من أجل إنشاء جزء من الكود يمكن تشغيله في سلسلة رسائل ، نقوم بإنشاء فئة ثم توسيع فئة الموضوع . يجب وضع المهمة التي يقوم بها هذا الجزء من التعليمات البرمجية في وظيفة run () .

في الكود أدناه ، يمكنك أن ترى أن العامل عبارة عن فئة تعمل على توسيع فئة مؤشر الترابط ، ويتم تنفيذ مهمة طباعة الأرقام من 0 إلى 5 داخل وظيفة run () .

class Worker extends Thread { @Override public void run() { for (int i = 0; i <= 5; i++) { System.out.println(Thread.currentThread().getName() + ": " + i); } } } 

في الكود أعلاه ، يتم استخدام Thread.currentThread (). getName () للحصول على اسم الخيط الحالي الذي يقوم بتشغيل الكود.

من أجل إنشاء سلسلة رسائل ، نحتاج فقط إلى إنشاء مثيل لفئة العامل. وبعد ذلك يمكننا بدء الخيط باستخدام وظيفة start () .

public class ThreadClassDemo { public static void main(String[] args) { Thread t1 = new Worker(); Thread t2 = new Worker(); Thread t3 = new Worker(); t1.start(); t2.start(); t3.start(); } } 

في الكود أعلاه ، نقوم بإنشاء 3 خيوط (t1 و t2 و t3) من فئة العامل. ثم نبدأ المواضيع باستخدام وظيفة start () .

إليك الكود النهائي لإنشاء سلسلة رسائل عن طريق تمديد فئة الموضوع:

class Worker extends Thread { @Override public void run() { for (int i = 0; i <= 5; i++) { System.out.println(Thread.currentThread().getName() + ": " + i); } } } public class ThreadClassDemo { public static void main(String[] args) { Thread t1 = new Worker(); Thread t2 = new Worker(); Thread t3 = new Worker(); t1.start(); t2.start(); t3.start(); } } 

هذا هو الإخراج الذي نحصل عليه من خلال تشغيل الكود أعلاه:

إخراج فئة الموضوع

يمكنك أن ترى أن جميع الخيوط الثلاثة قد طبعت الأرقام من 0 إلى 5.

يمكنك أيضًا أن ترى بوضوح من الإخراج أن الخيوط الثلاثة لا تعمل في أي تسلسل معين

تنفيذ واجهة التشغيل

من أجل إنشاء جزء من التعليمات البرمجية يمكن تشغيله في سلسلة رسائل ، نقوم بإنشاء فئة ثم تنفيذ الواجهة القابلة للتشغيل . يجب وضع المهمة التي يقوم بها هذا الجزء من التعليمات البرمجية في وظيفة run () .

في رمز أدناه يمكنك أن ترى أن RunnableWorker هي فئة التي تنفذ runnable واجهة، ومهمة أرقام الطباعة 0-4 يجري داخل المدى () وظيفة.

class RunnableWorker implements Runnable{ @Override public void run() { for (int i = 0; i <= 4; i++) { System.out.println(Thread.currentThread().getName() + ": " + i); } } } 

من أجل إنشاء موضوع، أولا نحن بحاجة إلى إنشاء مثيل من RunnableWorker الذي ينفذ runnable اجهة.

Then we can create a new thread by creating an instance of the thread class and passing the instance of RunnableWorker as the argument. This is shown in the code below:

public class RunnableInterfaceDemo { public static void main(String[] args) { Runnable r = new RunnableWorker(); Thread t1 = new Thread(r); Thread t2 = new Thread(r); Thread t3 = new Thread(r); t1.start(); t2.start(); t3.start(); } } 

The above code creates a runnable instance r. Then it create 3 threads (t1, t2 and t3) and passes r as the argument to the 3 threads. Then the start() function is used to start all 3 threads.

Here is the complete code for creating a thread by implementing the runnable interface:

class RunnableWorker implements Runnable{ @Override public void run() { for (int i = 0; i <= 4; i++) { System.out.println(Thread.currentThread().getName() + ": " + i); } } } public class RunnableInterfaceDemo { public static void main(String[] args) { Runnable r = new RunnableWorker(); Thread t1 = new Thread(r); Thread t2 = new Thread(r); Thread t3 = new Thread(r); t1.start(); t2.start(); t3.start(); } } 

On running the above code, we will get the following output. The sequence of the output will change every time the code is run.

خرج واجهة التشغيل

Implementing the runnable interface is a better option than extending the thread class since we can extend only one class, but we can implement multiple interfaces in Java.

Runnable Interface in Java 8

In Java 8, the runnable interface becomes a FunctionalInterface since it has only one function, run().

The below code shows how we can create a runnable instance in Java 8.

public class RunnableFunctionalInterfaceDemo { public static void main(String[] args) { Runnable r = () -> { for (int i = 0; i <= 4; i++) { System.out.println(Thread.currentThread().getName() + ": " + i); } }; Thread t1 = new Thread(r); Thread t2 = new Thread(r); Thread t3 = new Thread(r); t1.start(); t2.start(); t3.start(); } } 

Here, instead of creating a class and then implementing the runnable interface, we can directly use a lambda expression to create a runnable instance as shown below:

Runnable r = () -> { for (int i = 0; i <= 4; i++) { System.out.println(Thread.currentThread().getName() + ": " + i); } }; 

Code

The code in this article is available in the following GitHub repo: //github.com/aditya-sridhar/basic-threads-demo

Congrats ?

You now know how to create threads by extending the thread class and by implementing the runnable interface.

I will discuss the thread life cycle and challenges while using threads in my next blog post.

My Website: //adityasridhar.com/

لا تتردد في التواصل معي على LinkedIn أو متابعي على Twitter