ما الفرق بين Sequential, Concurrency, Parallelism ؟

السلام عليكم ورحمة الله وبركاته

وقت القراءة: 3 دقائق

المقدمة

سنشرح بشكل مبسط الفروق بين هذه المفاهيم الثلاثة Sequential, Concurrency, Parallelism

ملحوظة: الأكواد التي سأعرضها مجرد أكواد تخيلية من أجل الشرح لا أكثر المهم هنا أن الفكرة العامة تصل بشكل واضح

Sequential

لنفترض أولًا أننا لدينا 4 عمليات مختلفة وكل عملية تستغرق 1 ثانية
واحد فقط ونريده أن ينفذ هذه العمليات Thread ولنفترض أننا لدينا

الـ Sequential سينفذ العمليات بالتسلسل، واحدة تلو الأخرى بالترتيب
وكل عملية يجب أن تنتظر العملية السابقة لكي تبدأ

Thread.doTask(task_1); // ستستغرق 1 ثانية
Thread.doTask(task_2); // ستستغرق 1 ثانية
Thread.doTask(task_3); // ستستغرق 1 ثانية
Thread.doTask(task_4); // ستستغرق 1 ثانية

العمليات كلها استغرقت 4 ثواني، لأنها نُفذت بالتسلسل
والـ Thread يستطيع تنفيذ شيء واحد فقط في كل مرة

وكل عملية انتظرت التي قبلها كما ترى
إذا كانت كل عملية تعتمد بشكل كامل على نتيجة العملية السابقة
فالـ Sequential سيكون اختيار مثالي هنا
أما إذا كانت كل عملية مستقلة بذاتها فلن يكون خيارًا مثاليًا

Concurrency

لنفترض مجددًا أننا لدينا Thread واحد فقط ونريده أن ينفذ هذه العمليات
وكل عملية تستغرق 1 ثانية أيضًا

الـ Concurrency سينفذ العمليات بالتزامن، لكن ليس في نفس اللحظة
الـ Concurrency فكرته أنه يعطي لكل عملية وقت معين ليتعامل معها
حين ينتهي هذا الوقت ينتقل لعملية أخرى ثم يكرر الأمر لحين انتهاء جميع العمليات

لنعطي مثال للتوضيح، لنفترض أن الوقت الذي اعطاه لكل عملية هو ربع ثانية 250 ميلي ثانية
وكل عملية تستغرق 1 ثانية كما قلنا

while (true) {
  // طالما العملية لم تنتهي تعامل معها لمدة 250 مل فقط
  // وكرر نفس الأمر مع كل عملية لحين انتهاءهم جميعًا
  if (isTaskNotDone(task_1)) Thread.doTaskWithDuration(task_1, 250); // نفذها لمدة 250 مل فقط
  if (isTaskNotDone(task_2)) Thread.doTaskWithDuration(task_2, 250); // نفذها لمدة 250 مل فقط
  if (isTaskNotDone(task_3)) Thread.doTaskWithDuration(task_3, 250); // نفذها لمدة 250 مل فقط
  if (isTaskNotDone(task_4)) Thread.doTaskWithDuration(task_4, 250); // نفذها لمدة 250 مل فقط

  // لو كل العمليات انتهت أخرج
  if (allTasksDone([task_1, task_2, task_3, task_4])) break;
}

ستلاحظ أن الأربع عمليات ستنتهي بعد 4 ثواني في نفس اللحظة
بالتالي الـ Concurrency لا يقوم بالعمليات بالتوازي بالمعنى الذي قد يخطر على بالك
العمليات كانت تتبدل كل 250 مل لاننا نملك Thread واحد فقط
والـ Thread يستطيع تنفيذ شيء واحد فقط في كل مرة
ولا يستطيع تنفيذ أكثر من عملية في نفس اللحظة وهذا منطقي

Parallelism

ولنفترض هذه المرة أننا لدينا إثنين Thread وليس واحد
ومعنا 4 عمليات أيضًا وكل عملية تستغرق 1 ثانية

هنا في حالة أنه لدينا أكثر من Thread نستطيع أن نُنفذ الـ Parallelism
بحيث أن كل Thread سيأخذ مجموعة من العمليات لينفذها

// سينفذ العمليات التي عليه Thread_1 الـ
Thread_1.doTask(task_1); // ستستغرق 1 ثانية
Thread_1.doTask(task_2); // ستستغرق 1 ثانية

// سينفذ العمليات التي عليه Thread_2 في نفس اللحظة
Thread_2.doTask(task_3); // ستستغرق 1 ثانية
Thread_2.doTask(task_4); // ستستغرق 1 ثانية

العمليات كلها استغرقت ثانيتين فقط، لأنها نُفذت بالتوازي
كل Thread نفذ عمليتين إثنين بالتزامن مع الـ Thread الأخر في نفس اللحظة

لاحظ أن كل Thread نفذ العمليات بشكل Sequential
لكن بالطبع يمكننا أن نجعل كل Thread ينفذ عملياته بشكل Concurrency
لأن الـ Parallelism مجرد تعدد في الـ Thread
وكل Thread ينفذ عملياته سواء Sequential أو Concurrency