قوائم المهام في Java: من ThreadPoolExecutor إلى Disruptor

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

قوائم المهام في Java: من الآليات المدمجة إلى الأطر الحديثة



قوائم المهام (Task Queues) هي نمط أساسي لبناء تطبيقات Java قابلة للتوسع ومقاومة للأعطال. إنها تسمح بفصل منطق الأعمال عن إدارة الخيوط، وموازنة الحمل، ومعالجة المهام بشكل غير متزامن. في هذه المقالة، سنقوم بتحليل التطبيقات الرئيسية لقوائم المهام في Java، وهندستها، وأمثلة الكود، وسيناريوهات الاستخدام.



1. الآليات المدمجة: ThreadPoolExecutor و BlockingQueue



تقدم المكتبة القياسية لـ Java (java.util.concurrent) مجموعة قوية من الأدوات للعمل مع قوائم المهام. الأساس هو الفئة ThreadPoolExecutor، التي تدير مجموعة من الخيوط وتستخدم قائمة انتظار لتخزين المهام المنتظرة.



مثال أساسي:

import java.util.concurrent.*;

public class TaskQueueExample { public static void main(String[] args) { // إنشاء مجموعة خيوط: corePoolSize=2, maxPoolSize=4, قائمة انتظار تتسع لـ 100 مهمة ThreadPoolExecutor executor = new ThreadPoolExecutor( 2, // corePoolSize 4, // maximumPoolSize 60, // keepAliveTime TimeUnit.SECONDS, new LinkedBlockingQueue<>(100) // قائمة انتظار المهام );

// إرسال المهام for (int i = 0; i < 10; i++) { final int taskId = i; executor.submit(() -> { System.out.println("المهمة " + taskId + " يتم تنفيذها بواسطة الخيط " + Thread.currentThread().getName()); try { Thread.sleep(1000); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } }); }

// الإنهاء الصحيح executor.shutdown(); }}


أنواع قوائم الانتظار لـ ThreadPoolExecutor:

  • LinkedBlockingQueue — قائمة انتظار غير محدودة تعتمد على قائمة مرتبطة. مناسبة للأنظمة التي لا يُعرف فيها عدد المهام مسبقًا.
  • ArrayBlockingQueue — قائمة انتظار محدودة تعتمد على مصفوفة. تسمح بالتحكم في الحد الأقصى لعدد المهام المنتظرة.
  • SynchronousQueue — قائمة انتظار بدون سعة: كل put() ينتظر take(). تُستخدم للتسليم المباشر للمهام إلى الخيوط.
  • PriorityBlockingQueue — قائمة انتظار ذات أولوية. يتم فرز المهام وفقًا لمقارن محدد.


2. بنية Producer-Consumer القائمة على قوائم الانتظار



يمكن تنفيذ النمط الكلاسيكي Producer-Consumer بسهولة باستخدام BlockingQueue. يضع المنتجون (producers) المهام في قائمة الانتظار، ويقوم المستهلكون (consumers) بسحبها للمعالجة.



مثال على التنفيذ:

import java.util.concurrent.*;

public class ProducerConsumerExample { private static final BlockingQueue<String> queue = new LinkedBlockingQueue<>(5);

static class Producer implements Runnable { @Override public void run() { try { for (int i = 0; i < 10; i++) { String task = "مهمة-" + i; queue.put(task); // يتم الحظر إذا كانت قائمة الانتظار ممتلئة System.out.println("تم إنتاج: " + task); Thread.sleep(100); } } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } }

static class Consumer implements Runnable { @Override public void run() { try { while (true) { String task = queue.take(); // يتم الحظر إذا كانت قائمة الانتظار فارغة System.out.printl

توصيات