ডেমন থ্রেড বনাম ইউজার থ্রেড

জাভার প্রতিটি থ্রেড একটি বুলিয়ান ফ্ল্যাগ বহন করে, যা একটি প্রশ্নের উত্তর দেয়: জেভিএম কি শাটডাউনের আগে এই থ্রেডটির জন্য অপেক্ষা করবে? এই ফ্ল্যাগই ইউজার (নন-ডেমন) থ্রেডকে ডেমন থ্রেড থেকে আলাদা করে। প্রতিটি জাভা ডেভেলপার একসময় যে প্রশ্নটি করে—"আমার প্রোগ্রাম বন্ধ হচ্ছে না কেন?"—তার পুরো প্রক্রিয়া এই ফ্ল্যাগের ওপর নির্ভরশীল।

নিয়ম

জেভিএম ততক্ষণ চলতে থাকে যতক্ষণ কমপক্ষে একটি নন-ডেমন থ্রেড জীবিত থাকে। কতগুলো ডেমন থ্রেড এখনও চলছে, সেটা কোনো ব্যাপার নয়—শেষ ইউজার থ্রেডটি শেষ হওয়ার মুহূর্তেই জেভিএম প্রক্রিয়াটি সঙ্গে সঙ্গে বন্ধ করে দেয়, ডেমন থ্রেডগুলোকেও, তাদের কাজ শেষ হওয়ার সুযোগ না দিয়েই।

public class DaemonExample {
    public static void main(String[] args) throws InterruptedException {
        Thread daemon = new Thread(() -> {
            int tick = 0;
            while (true) {
                System.out.println("daemon tick " + (++tick));
                try {
                    Thread.sleep(300);
                } catch (InterruptedException e) {
                    return;
                }
            }
        });
        daemon.setDaemon(true); // start() এর আগে সেট করতে হবে
        daemon.start();

        Thread.sleep(1000); // main, একটি ইউজার থ্রেড, কিছু কাজ করল
        System.out.println("main শেষ, এখন জেভিএম বন্ধ হয়ে যাবে");
        // এখানে daemon.join() নেই - জেভিএম এর জন্য অপেক্ষা করবে না
    }
}

এই কোডটি চালালে "main শেষ" প্রিন্ট হওয়ার কিছুক্ষণ পরেই প্রোগ্রাম বন্ধ হয়ে যায়, যদিও daemon থ্রেডের অসীম লুপ কখনো নিজে থেকে ফেরার সুযোগ পায়নি। setDaemon(true) কলটি start()-এর আগে দিতেই হবে; ইতিমধ্যে শুরু হয়ে যাওয়া থ্রেডে এটি কল করলে IllegalThreadStateException ছোঁড়া হয়।

আপনি ইতিমধ্যে যেসব থ্রেড ব্যবহার করেন সেগুলো ডেমন

এই সিরিজের প্রথম আর্টিকেলে দেখা জেভিএম-অভ্যন্তরীণ থ্রেডগুলো (গার্বেজ কালেকশন থ্রেড, জেআইটি কম্পাইলার থ্রেড, সিগন্যাল ডিসপ্যাচার) সবই ডেমন। ঠিক এ কারণেই এরা কখনো একটি সাধারণ main মেথডকে বন্ধ হতে বাধা দেয় না: এদের কাজ চলমান প্রোগ্রামকে সেবা দেওয়া, প্রোগ্রাম যেসব কাজের জন্য অপেক্ষা করে তা নয়।

ব্যবহারিক শিক্ষা

ডেমন থ্রেড ব্যাকগ্রাউন্ডের গৃহস্থালির কাজের জন্য উপযুক্ত, যেখানে হঠাৎ, অসমাপ্ত থামা গ্রহণযোগ্য—যেমন নির্দিষ্ট সময় পরপর ক্যাশে থেকে পুরনো ডাটা সরানো বা মেট্রিক্স সংগ্রহ করা। কিন্তু যেকোনো কাজ যা অবশ্যই সম্পন্ন করতে হবে—যেমন রাইট-অ্যাহেড লগ ফ্লাশ করা বা নেটওয়ার্ক রেসপন্স শেষ করা—তার জন্য ডেমন থ্রেড ভুল পছন্দ, কারণ জেভিএম ডেমন থ্রেডকে মাঝপথেই, কোনো পরিষ্করণ বা সতর্কতা ছাড়াই, কেটে ফেলতে পারে এবং ফেলবেও।

যখন কোনো কাজ শেষ হতে দেওয়া বাধ্যতামূলক, তখন হয় নন-ডেমন থ্রেড ব্যবহার করুন, নয়তো একটি ডেমন থ্রেড পুলের সঙ্গে সুস্পষ্ট, ব্লকিং শাটডাউন ধাপ (ExecutorService.shutdown() এবং তারপর awaitTermination()) ব্যবহার করুন—যাতে অপেক্ষার নিয়ন্ত্রণ অ্যাপ্লিকেশনের হাতে থাকে, ভাগ্যের ওপর ছেড়ে না দেওয়া হয়।

Share