wait() مقابل sleep() في جافا: أيهما تختار للخيوط؟

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

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

ابدأ الدورة

wait() مقابل sleep() في جافا: معركة عمالقة تعدد الخيوط

\n\n

تخيل أنك قائد أوركسترا. لديك عازفو كمان (خيوط) يجب أن يعزفوا بتناغم، لكن في بعض الأحيان يحتاجون إلى الانتظار حتى ينتهي الآخرون من مقطوعتهم. في جافا، لإدارة مثل هذه التوقفات، هناك أداتان قويتان: wait() و sleep(). للوهلة الأولى، تبدوان متشابهتين - كلاهما يجعل الخيط "يتجمد" لفترة. لكن في الواقع، هما آليتان مختلفتان تمامًا، والخلط بينهما هو طريقة مؤكدة للحصول على deadlock أو race condition.

\n\n

هذه المقالة هي دليلك في غابة تعدد الخيوط. لن نقوم فقط بسرد الاختلافات، بل سنحللها بأمثلة حية، حتى تتذكر إلى الأبد: sleep هي توقف مؤقت، و wait هي تحرير للمورد. هيا بنا!

\n\n

ما هو sleep()؟ (Thread.sleep)

\n\n

الطريقة Thread.sleep(ميلي ثانية) هي أبسط طريقة "لإسبات" الخيط الحالي لفترة زمنية محددة. الخيط ببساطة يستريح، دون تحرير الأقفال (locks) من الكائنات. إنه مثل قطة كسولة تغفو على الأريكة، لكنها لا تزال تمسك بلعبتها بمخلبها.

\n\n

حقائق مهمة عن sleep():

\n
    \n
  • هي طريقة ثابتة من الفئة Thread.
  • \n
  • الخيط لا يحرر الشاشات (monitors) (الأقفال) التي يحتفظ بها.
  • \n
  • بعد انتهاء المؤقت، ينتقل الخيط إلى الحالة Runnable (جاهز للتنفيذ).
  • \n
  • قد ترمي InterruptedException.
  • \n
\n\n

مثال بسيط:

\n
public class SleepExample {\n    public static void main(String[] args) throws InterruptedException {\n        System.out.println("نبدأ: " + System.currentTimeMillis());\n        Thread.sleep(2000); // ننام لمدة 2 ثانية\n        System.out.println("استيقظنا: " + System.currentTimeMillis());\n    }\n}
\n\n

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

\n\n

ما هو wait()؟ (Object.wait)

\n\n

الطريقة wait() ليست مجرد توقف مؤقت، بل هي آلية للتواصل بين الخيوط. تم تعريفها في الفئة Object، ولا يمكن استدعاؤها إلا داخل كتلة متزامنة (synchronized). عندما يستدعي الخيط wait()، فإنه:

\n
    \n
  • يحرر شاشة الكائن (أي يطلق القفل).
  • \n
  • ينتقل إلى الحالة WAITING أو TIMED_WAITING (إذا تم تحديد مهلة).
  • \n
  • ينتظر حتى يقوم خيط آخر باستدعاء notify() أو notifyAll() على نفس الكائن.
  • \n
\n\n

هذا كما لو كنت تقول: "أنا أضع الشوكة وأنتظر حتى يتم إحضار الطبق الثاني لي". أنت لا تنام فقط - بل تفرغ مكانًا على الطاولة لشخص آخر.

\n\n

مثال أساسي:

\n
public class WaitNotifyExample {\n    private static final Object lock = new Object();\n\n    public static void main(String[] args) throws InterruptedException {\n        Thread waiter = new Thread(() -> {\n            synchronized (lock) {\n                try {\n                    System.out.println("خيط النادل ينتظر...");\n                    lock.wait(); // يحرر القفل وينتظر\n                    System.out.println("خيط النادل تلقى الإشعار!");\n                } catch (InterruptedException e) {\n                    Thread.currentThread().interrupt();\n                }\n            }\n        });\n\n        Thread notifier = new Thread(() -> {\n            synchronized (lock) {\n                System.out.println("خيط الطباخ يطبخ...");\n                try {\n                    Thread.sleep(1000); // محاكاة الطبخ\n                } catch (InterruptedException e) {\n                    Thread.currentThread().interrupt();\n                }\n                lock.notify(); // يوقظ الخيط المنتظر\n                System.out.println("الطباخ أبلغ النادل!");\n            }\n        });\n\n        waite                

المدونات

توصيات الكتب