فرض کن برنامه جاوای تو یه کارخانه بزرگ تولیدی هست و پردازنده (CPU) همون مدیر خط تولید است. در این صورت، Threadها کارگرهای این کارخونه هستن که قراره کارهای مختلف رو پیش ببرن. حالا بیا چرخه حیات یک Thread (یا همون کارگر کارخونه) رو تو ۶ مرحله با این دیدگاه جدید بررسی کنیم:

۱. وضعیت NEW (فرم استخدام روی میز )

وقتی تو کد مینویسی Thread t = new Thread();، مثل اینه که یه کارگر جدید استخدام کردی و فرم استخدامش رو پر کردی. این کارگر الان وجود داره، اسم داره، ولی هنوز لباس کار نپوشیده و وارد کارخونه نشده. تو این حالت، Thread ما هیچ منبعی از سیستم رو درگیر نکرده و تو وضعیت NEW قرار داره.

۲. وضعیت RUNNABLE (حضور در خط تولید )

وقتی متد t.start() رو صدا می‌زنی، کارگر ما لباس کارش رو میپوشه و میره تو خط تولید می ایسته. وضعیت RUNNABLE دو حالت داره:

  • یا مدیر خط تولید (CPU) بهش کار داده و داره واقعاً کار میکنه.
  • یا تو صف ایستاده و منتظره تا مدیر بهش اشاره کنه و بگه: «حالا نوبت توئه، شروع کن!» چون پردازنده با سرعت نور بین Threadها جابه‌جا میشه، ما به هر دو حالت میگیم Runnable (یعنی آماده‌ی کار).

۳. وضعیت BLOCKED (دعوا سر آچار فرانسه! )

فرض کن دو تا کارگر برای انجام کارشون به یک دستگاه جوشکاری خاص (یا یه بلوک synchronized تو کد) نیاز دارن. کارگر اول دستگاه رو برمیداره و مشغول میشه. وقتی کارگر دوم میرسه، میبینه دستگاه دست کس دیگه‌ایه. پس مجبوره همونجا دست به سینه بایسته تا کارگر اول کارش تموم بشه. به این حالتِ گیر افتادن پشت یک قفل (Lock)، میگن وضعیت BLOCKED.

۴. وضعیت WAITING (منتظر رسیدن قطعات )

گاهی اوقات کارگر ما به یه جایی از کار میرسه که میبینه قطعات لازم هنوز از بخش دیگه نیومده. خودش کار رو متوقف میکنه و میگه: «من اینجا وایمیستم تا یکی بهم خبر بده قطعات رسید». وقتی از متدهایی مثل wait() یا join() (بدون تعیین زمان) استفاده میکنی، Thread وارد حالت WAITING میشه. این کارگر تا زمانی که یه کارگر دیگه صداش نزنه (مثلاً با notify())، همونجا منتظر میمونه.

۵. وضعیت TIMED_WAITING (استراحت زمان ‌دار)

این حالت مثل اینه که کارگر ما یه تایمر کوک میکنه و میگه: «من دقیقاً ۱۰ دقیقه میرم استراحت و چای میخورم، بعدش خودم برمیگردم سر کار». وقتی تو کد مینویسی Thread.sleep(1000); (یعنی هزار میلی‌ثانیه بخواب)، Thread وارد حالت TIMED_WAITING میشه. تفاوتش با حالت قبلی اینه که اینجا نیازی نیست کسی بیدارش کنه؛ زمانش که تموم بشه، خودش برمیگرده تو صف RUNNABLE.

۶. وضعیت TERMINATED (پایان شیفت کاری)

وقتی کدهای داخل متد run() تا خط آخر اجرا بشن، یعنی شیفت کاریِ کارگر ما تموم شده. وسایلش رو جمع میکنه، کارت میزنه و میره خونه. این میشه وضعیت TERMINATED. یادت باشه تو جاوا، کارگری که شیفتش تموم شده رو نمیتونی دوباره با دستور start() برگردونی سر همون کار؛ باید یه کارگر (Thread) جدید استخدام کنی!

 

ببین تو کد چطور این وضعیت ‌ها تغییر میکنن:

public class FactoryWorker {
    public static void main(String[] args) throws InterruptedException {
        // ۱. استخدام کارگر (NEW)
        Thread worker = new Thread(() -> {
            System.out.println("کارگر: دارم قطعات رو مونتاژ می‌کنم...");
        });
        System.out.println("وضعیت بعد از استخدام: " + worker.getState());
// ۲. فرستادن کارگر به خط تولید (RUNNABLE)
        worker.start();
        System.out.println("وضعیت بعد از شروع کار: " + worker.getState());
// مدیر (Thread اصلی) صبر می‌کنه تا شیفت کارگر تموم بشه
        worker.join();
// ۳. پایان شیفت (TERMINATED)
        System.out.println("وضعیت بعد از پایان کار: " + worker.getState());
    }
}

جمع بندی

مثال کارخونه خیلی خوب نشون میده که Threadها چطور با هم درگیر میشن، سر منابع مشترک رقابت میکنن یا منتظر هم میمونن. 

مدیریت Threadها تو جاوا (یا همون Multithreading) یکی از اون مباحثیه که اولش ممکنه ترسناک به نظر برسه، ولی وقتی چرخه حیاتشون رو مثل رفتار آدم‌ها در نظر بگیری، خیلی شیرین و منطقی میشه.