daemon เธรดใน Java คืออะไร


809

ใครช่วยบอก daemon ว่ามีเธรดอะไรในJavaบ้าง?


20
ThreadJavadoc อธิบายถึงสิ่งที่พวกเขาจะ: java.sun.com/javase/6/docs/api/java/lang/Thread.html
skaffman


2
สำหรับ Daemon Threads เมื่อ JVM หยุดทำงานเธรด daemon ทั้งหมดจะถูกออกเนื่องจากเหตุผลนี้ไม่ควรใช้เธรด daemon บ่อยครั้งเนื่องจากการล้างข้อมูลอาจไม่สามารถเรียกใช้งานได้ ตัวอย่างเช่น I / O ใด ๆ จะไม่ออกอย่างสง่างามและเขียน / อ่านไปจนจบ
msj121

คำตอบ:


631

daemon thread เป็นเธรดที่ไม่ป้องกัน JVM จากการออกเมื่อโปรแกรมเสร็จสิ้น แต่เธรดยังคงทำงานอยู่ ตัวอย่างสำหรับเธรด daemon คือการรวบรวมขยะ

คุณสามารถใช้setDaemon(boolean)วิธีการเปลี่ยนThreadคุณสมบัติ daemon ก่อนที่เธรดจะเริ่มทำงาน


210
สำหรับรุ่นหลังsetDamon(boolean)สามารถเรียกได้ก่อนที่จะเริ่มเธรด โดยดีฟอลต์เธรดจะสืบทอดสถานะ daemon ของเธรดพาเรนต์
สีเทา

1
"ไม่ได้ป้องกัน JVM จากการออกเมื่อโปรแกรมเสร็จสิ้น แต่เธรดยังคงทำงานอยู่" ในขณะที่ @sateesh บอกว่า "JVM หยุดเธรด daemon ที่เหลืออยู่ใด ๆ " daemon เธรดจะทำงานเสร็จสิ้นเมื่อ JVM ออกแล้ว
เจอรัลด์

23
@Galdald เธรดทั้งหมดจะถูกฆ่าเมื่อ JVM ออก B_erb พูดว่า "... เมื่อโปรแกรมเสร็จสิ้น" สิ่งที่หมายถึงคือถ้าโปรแกรมไม่ฆ่า JVM อย่างชัดเจนจากนั้น JVM จะฆ่าตัวเองโดยอัตโนมัติเมื่อเธรดที่ไม่ใช่ไดมอนสิ้นสุดลง เธรดปกติจะกำหนด "เมื่อโปรแกรมออกจาก" เธรดภูตไม่
โซโลมอนช้า

2
ดังนั้นบรรทัดนี้thread that does not prevent the JVM from exiting when the program finishes but the thread is still runningโดยทั่วไปหมายถึงกระบวนการ JVM ที่เริ่มเธรดไม่สนใจว่า daemon เธรดดำเนินการเสร็จหรือไม่ก็จะจบลงเองถ้าเธรดปกติทั้งหมดเสร็จสิ้นการดำเนินการ
Bhargav

1
@SolomonSlow อะไรคือผลที่ตามมาของการฆ่า daemon thread (ตัวอย่างเช่นตัวรวบรวมขยะ) ในขณะที่มันยังทำงานอยู่เมื่อ JVM สิ้นสุดลง? ขอบคุณ
Venkat Ramakrishnan

340

อีกสองสามคะแนน (การอ้างอิง: Java Concurrency ในทางปฏิบัติ )

  • เมื่อสร้างเธรดใหม่มันจะสืบทอดสถานะ daemon ของพาเรนต์
  • เมื่อเธรดที่ไม่ใช่ daemon ทั้งหมดเสร็จสิ้น JVM จะหยุดและเธรด daemonที่เหลือจะถูกทิ้ง :

    • ในที่สุดบล็อกยังไม่ได้ดำเนินการ ,
    • สแต็คไม่ได้คลายออก - JVM เพิ่งจะออก

    เนื่องจากเหตุผลนี้จึงควรใช้เธรด daemon อย่างประหยัดและเป็นอันตรายที่จะใช้เธรดเหล่านี้สำหรับงานที่อาจทำ I / O ประเภทใดก็ได้


3
เหตุใดเธรด daemon จึงไม่ควรใช้สำหรับ I / O มันเป็นความกังวลเกี่ยวกับ BufferedWriters และอื่น ๆ ที่ไม่ถูกล้างออกหรือไม่?
Paul Cager

4
@ PaulCager ใช่พวกเขาสามารถถูกตัดหัวเข่าตรงกลางของการเขียน / อ่านได้เช่นกัน
Cruncher

52
ประเด็นที่สองไร้สาระ เมื่อ JVM หยุดทำงานเธรดทั้งหมดจะหยุดทำงานและไม่มีfinallyบล็อกถูกดำเนินการไม่ว่าเธรดนั้นจะเป็น daemon หรือไม่ก็ตาม ดังนั้นอย่าโทรSystem.exit(…)ถ้าคุณคิดว่าอาจมีกระทู้ที่กำลังทำ I / O อยู่ ข้อแตกต่างเพียงอย่างเดียวคือ JVM จะทริกเกอร์การเลิกจ้างของตนเองเมื่อเหลือ daemon เธรดเท่านั้น
Holger

11
"สแตกไม่คลาย" หมายความว่าอย่างไร
ɢʜʘʂʈʀɛɔʘɴ

2
@ ɢʜʘʂʈʀɛɔʘɴมีคำอธิบายบางอย่างเกี่ยวกับ "กองที่คลี่คลาย" ซึ่งรวมถึงสิ่งนี้: flylib.com/books/en/2.254.1.277/1
766353

175

คำตอบข้างต้นทั้งหมดเป็นสิ่งที่ดี นี่คือข้อมูลโค้ดสั้น ๆ ง่ายๆเพื่อแสดงให้เห็นถึงความแตกต่าง ลองใช้กับแต่ละค่าของจริงและเท็จsetDaemonมา

public class DaemonTest {

    public static void main(String[] args) {
        new WorkerThread().start();

        try {
            Thread.sleep(7500);
        } catch (InterruptedException e) {
            // handle here exception
        }

        System.out.println("Main Thread ending") ;
    }

}

class WorkerThread extends Thread {

    public WorkerThread() {
        // When false, (i.e. when it's a user thread),
        // the Worker thread continues to run.
        // When true, (i.e. when it's a daemon thread),
        // the Worker thread terminates when the main 
        // thread terminates.
        setDaemon(true); 
    }

    public void run() {
        int count = 0;

        while (true) {
            System.out.println("Hello from Worker "+count++);

            try {
                sleep(5000);
            } catch (InterruptedException e) {
                // handle exception here
            }
        }
    }
}

2
@russ ข้อมูลโค้ดที่ดี! ฉันต้องกำหนดคลาส WorkerThread เป็นแบบสแตติก
xli

@xli คุณจะได้ทำใหม่ DaemonTest () WorkerThread ใหม่ () เริ่มต้น () มากเกินไป :)..
abhy

@ รัสเป็นตัวอย่างที่ดี ฉันได้ตระหนักถึงการที่หนึ่งเริ่มต้นคือ "setDeamon (เท็จ)" ถ้าคุณไม่ได้กำหนดอย่างชัดเจน "setDaemon (จริง)"
huseyin

96

โดยปกติแล้วกระบวนการ daemon ใน UNIX นั้นเป็นกระบวนการที่ทำงานอยู่เบื้องหลังเสมอเหมือนบริการใน Windows

เธรด daemon ใน Java เป็นสิ่งที่ไม่ป้องกัน JVM จากการออก โดยเฉพาะ JVM จะออกจากเมื่อ daemon ยังคงอยู่ในเธรดเท่านั้น คุณสามารถสร้างหนึ่งโดยการเรียกวิธีการในการsetDaemon()Thread

ได้อ่านของหัวข้อภูต


3
ลิงก์ของคุณเสียชีวิต ณ จุดนี้บางทีคุณอาจต้องการอัปเดต อย่างไรก็ตาม +1 สำหรับคุณ
Jasonw

2
ฉันชอบการเปรียบเทียบระหว่าง UNIX และ Windows
Premraj

คำอธิบายที่ดีที่สุดที่นี่!
LoveMeow

57

เธรด Daemon เปรียบเสมือนผู้ให้บริการสำหรับเธรดหรือออบเจ็กต์อื่นที่กำลังทำงานในกระบวนการเดียวกันกับเธรด daemon เธรด Daemon ใช้สำหรับงานที่สนับสนุนพื้นหลังและจำเป็นเฉพาะในขณะที่เธรดปกติกำลังทำงาน หากเธรดปกติไม่ได้ทำงานและเธรดที่เหลืออยู่เป็นเธรด daemon ตัวแปลจะออก

ตัวอย่างเช่นเบราว์เซอร์ HotJava ใช้เธรด daemon ถึงสี่ชื่อ "Image Fetcher" เพื่อดึงรูปภาพจากระบบไฟล์หรือเครือข่ายสำหรับเธรดที่ต้องการ

โดยทั่วไปแล้วเธรด Daemon จะใช้เพื่อดำเนินการบริการสำหรับแอปพลิเคชัน / แอปเพล็ตของคุณ (เช่นการโหลด "fiddley bits") ความแตกต่างที่สำคัญระหว่างเธรดผู้ใช้และเธรด daemon คือ JVM จะปิดโปรแกรมเมื่อเธรดผู้ใช้ทั้งหมดถูกยกเลิก เธรด Daemon จะถูกยกเลิกโดย JVM เมื่อไม่มีเธรดผู้ใช้ที่กำลังรันอีกต่อไปรวมถึงเธรดหลักของการดำเนินการ

setDaemon (จริง / เท็จ)? เมธอดนี้ใช้เพื่อระบุว่าเธรดคือ daemon thread

บูลีนสาธารณะ isDaemon ()? วิธีนี้ใช้เพื่อกำหนดว่าเธรดคือ daemon หรือไม่

เช่น:

public class DaemonThread extends Thread {
    public void run() {
        System.out.println("Entering run method");

        try {
            System.out.println("In run Method: currentThread() is" + Thread.currentThread());

            while (true) {
                try {
                    Thread.sleep(500);
                } catch (InterruptedException x) {}

                System.out.println("In run method: woke up again");
            }
        } finally {
            System.out.println("Leaving run Method");
        }
    }
    public static void main(String[] args) {
        System.out.println("Entering main Method");

        DaemonThread t = new DaemonThread();
        t.setDaemon(true);
        t.start();

        try {
            Thread.sleep(3000);
        } catch (InterruptedException x) {}

        System.out.println("Leaving main method");
    }

}

เอาท์พุท:

C:\java\thread>javac DaemonThread.java

C:\java\thread>java DaemonThread
Entering main Method
Entering run method
In run Method: currentThread() isThread[Thread-0,5,main]
In run method: woke up again
In run method: woke up again
In run method: woke up again
In run method: woke up again
In run method: woke up again
In run method: woke up again
Leaving main method

C:\j2se6\thread>

37

คำจำกัดความของ Daemon (การคำนวณ):

กระบวนการพื้นหลังที่จัดการการร้องขอบริการเช่นการเก็บพักงานพิมพ์และการถ่ายโอนไฟล์และหยุดทำงานเมื่อไม่จำเป็น

—— แหล่งที่มา: ภาษาอังกฤษโดยพจนานุกรม Oxford

Daemon thread ใน Java คืออะไร

  • เธรด Daemon สามารถปิดได้ตลอดเวลาระหว่างโฟลว์ Non-Daemon เช่นผู้ใช้เธรดดำเนินการอย่างสมบูรณ์
  • เธรด Daemon เป็นเธรดที่รันเป็นระยะ ๆ ในพื้นหลังตราบใดที่เธรดที่ไม่ใช่ daemon กำลังรันอยู่
  • เมื่อเธรดที่ไม่ใช่ daemon ทั้งหมดเสร็จสมบูรณ์ daemon เธรดจะถูกยกเลิกโดยอัตโนมัติ
  • Daemon threads เป็นผู้ให้บริการสำหรับเธรดผู้ใช้ที่ทำงานในกระบวนการเดียวกัน
  • JVM ไม่สนใจเกี่ยวกับ daemon เธรดที่จะทำให้เสร็จเมื่ออยู่ในสถานะ Running แม้กระทั่งในที่สุดบล็อกก็ยังยอมให้ดำเนินการได้ JVM มีการกำหนดค่าตามความชอบสำหรับเธรดที่ไม่ใช่ daemon ที่สร้างโดยเรา
  • เธรด Daemon ทำหน้าที่เป็นบริการใน Windows
  • JVM หยุดเธรด daemon เมื่อเธรดผู้ใช้ทั้งหมด (ตรงกันข้ามกับเธรด daemon) ถูกยกเลิก ดังนั้น daemon threads สามารถใช้เพื่อนำไปใช้ตัวอย่างเช่นฟังก์ชันการตรวจสอบเมื่อเธรดหยุดทำงานโดย JVM ทันทีที่เธรดผู้ใช้ทั้งหมดหยุดทำงาน

ถ้าคุณเรียกใช้ System.exit () บล็อกสุดท้ายจะไม่ถูกเรียกใช้งานโดยไม่คำนึงถึงเธรดที่เป็นเธรด daemon แน่นอนที่สุดบล็อกจะถูกดำเนินการใน daemon เธรดแม้หลังจากที่เธรดผู้ใช้ล่าสุดยุติหาก JVM ยังไม่ฆ่าเธรดเลย
benez

5
daemon เธรดดำเนินการที่ระดับความสำคัญเดียวกับเธรดการสร้างยกเว้นว่ามีการเปลี่ยนแปลงก่อนที่จะเริ่มต้น เธรดภูตไม่จำเป็นต้องเป็น 'ผู้ให้บริการ' หรือบริการ Windows หรืออย่างอื่นที่ระบุไว้ที่นี่: เป็นเพียงเธรดที่ไม่ได้ป้องกัน JVM จากการออก ระยะเวลา
user207421

35

ด้ายภูตเป็นหัวข้อที่ถือว่าทำงานบางอย่างในพื้นหลังเช่นการจัดการแสดงหรือ chronjobs ต่างๆที่สามารถอยู่ในใบสมัคร

เมื่อโปรแกรมของคุณมีdaemonเหลือเพียงเธรดเท่านั้นโปรแกรมจะออกจากโปรแกรม นั่นเป็นเพราะโดยทั่วไปแล้วเธรดเหล่านี้จะทำงานร่วมกับเธรดปกติและให้การจัดการพื้นหลังของเหตุการณ์

คุณสามารถระบุว่า a Threadเป็นdaemonโดยใช้setDaemonวิธีการพวกเขามักจะไม่ออกและไม่ถูกขัดจังหวะ .. พวกเขาจะหยุดเมื่อแอปพลิเคชันหยุด


1
มันเป็นเพราะมันเป็นดีมอนภูตและนั่นคือความหมายของ 'ภูต' เหตุผลของคุณกลับไปข้างหน้า
user207421

15

หนึ่งความเข้าใจผิดที่ฉันต้องการชี้แจง:

  • สมมติว่าถ้า daemon thread (say B) ถูกสร้างขึ้นภายใน thread ผู้ใช้ (say A); จากนั้นการสิ้นสุดของเธรดผู้ใช้ / เธรดผู้ใช้นี้ (A) จะไม่จบเธรด daemon / child thread (B) ที่สร้างขึ้น เธรดผู้ใช้ที่ระบุเป็นหนึ่งเดียวที่กำลังทำงานอยู่
  • ดังนั้นจึงไม่มีความสัมพันธ์พ่อแม่และลูกเมื่อสิ้นสุดเธรด daemon เธรดทั้งหมด (โดยไม่คำนึงถึงตำแหน่งที่สร้างขึ้น) จะสิ้นสุดลงเมื่อไม่มีเธรดผู้ใช้ live เดียวและทำให้ JVM สิ้นสุดการทำงาน
  • แม้สิ่งนี้จะเป็นจริงสำหรับทั้งสอง (parent / child) คือ daemon threads
  • หากเธรดลูกที่สร้างจากเธรด daemon นั่นก็เป็นเธรด daemon เช่นกัน สิ่งนี้จะไม่ต้องการการตั้งค่าการตั้งค่าเธรดภูตที่ชัดเจน ในทำนองเดียวกันถ้าเธรดลูกที่สร้างขึ้นจากเธรดผู้ใช้ดังนั้นนั่นคือเธรดผู้ใช้หากคุณต้องการเปลี่ยนการตั้งค่าแฟล็ก daemon จำเป็นต้องมีก่อนการเริ่มเธรดย่อยนั้น

สิ่งนี้ไม่ได้ยกมาจากอะไรเลย อย่าใช้การจัดรูปแบบคำพูดสำหรับข้อความที่ไม่ได้ยกมา วรรคแรกของ 'ใบเสนอราคา' ไม่ถูกต้องและขัดแย้งกับที่สอง
user207421

@EJP มีมันดังนั้นทุกคนจะต้องให้คนอื่นพูดที่นี่ไม่ใช่ของตัวเอง หรือตัวเรามีการพูดที่ไหนสักแห่งแล้วชี้ที่นี่?
Kanagavelu Sugumar

ใช่ถ้าคุณพูดถึงใครบางคนที่คุณต้องอ้างอิงพวกเขาเช่นเดียวกับที่อื่นบิตถ้าคุณยังไม่ได้อ้างใครก็ตามที่ไม่ได้จัดรูปแบบเหมือนที่คุณมี ฉันไม่สามารถทำหัวหรือก้อยของประโยคที่สองของคุณ
user207421

12

Daemon Thread และเธรดผู้ใช้ โดยทั่วไปเธรดทั้งหมดที่สร้างขึ้นโดยโปรแกรมเมอร์คือเธรดผู้ใช้ (เว้นแต่คุณจะระบุว่าเป็น daemon หรือพาเรนต์เธรดของคุณคือเธรด daemon) โดยทั่วไปเธรดผู้ใช้มีความหมายเพื่อเรียกใช้รหัสโปรแกรมของเรา JVM จะไม่ยุติลงเว้นแต่ว่าเธรดผู้ใช้ทั้งหมดจะยุติลง


10

Java มีเธรดชนิดพิเศษที่เรียกว่าdaemon thread

  • ลำดับความสำคัญต่ำมาก
  • รันเฉพาะเมื่อไม่มีเธรดอื่นของโปรแกรมเดียวกันทำงานอยู่
  • JVM สิ้นสุดโปรแกรมที่ทำเธรดเหล่านี้ให้เสร็จสิ้นเมื่อ daemon threads เป็นเธรดเดียวที่รันในโปรแกรม

daemon เธรดใดที่ใช้ทำอะไร

โดยปกติใช้เป็นผู้ให้บริการสำหรับเธรดปกติ โดยทั่วไปจะมีการวนซ้ำไม่สิ้นสุดที่รอคำขอบริการหรือดำเนินการกับเธรด พวกเขาไม่สามารถทำงานที่สำคัญได้ (เพราะเราไม่รู้ว่าเมื่อไหร่ที่พวกเขาจะมีเวลา CPU และพวกเขาสามารถเสร็จสิ้นเมื่อใดก็ได้หากไม่มีเธรดอื่นทำงานอยู่)

ตัวอย่างทั่วไปของชนิดของหัวข้อเหล่านี้เป็นคนเก็บขยะ Java

ยังมีอีก...

  • คุณเรียกsetDaemon()เมธอดก่อนที่จะเรียกใช้start()เมธอดเท่านั้น เมื่อเธรดกำลังทำงานคุณจะไม่สามารถแก้ไขสถานะ daemon ได้
  • ใช้isDaemon()วิธีการตรวจสอบว่าเธรดเป็นเธรด daemon หรือเธรดผู้ใช้

8
-1 ฉันไม่เชื่อว่า daemon thread มีความสำคัญต่ำ แน่นอนว่าไม่มีเอกสารใดที่ฉันเคยเห็น คำตอบ SO นี้อ้างว่าลำดับความสำคัญและ daemon-ness เป็นแบบฉาก: stackoverflow.com/a/10298353/839128
MikeFHay

5
เธรด Daemon ไม่มีส่วนเกี่ยวข้องกับลำดับความสำคัญ คุณสามารถมีเธรด daemon ลำดับความสำคัญสูงหรือเธรดที่ไม่ใช่ daemon ลำดับความสำคัญต่ำ
สีเทา

เธรด daemon เริ่มแรกมีความสำคัญเท่ากับการสร้างเธรด
user207421

คำสั่ง "'จะทำงานเมื่อไม่มีเธรดอื่นของโปรแกรมเดียวกันทำงานอยู่" ทำให้เข้าใจผิด
Fredrick Gauss

9

เธรดภูตเป็นเหมือนผู้ช่วย เธรดที่ไม่ใช่ Daemon เป็นเหมือนนักแสดงด้านหน้า ผู้ช่วยช่วยให้นักแสดงสามารถทำงานให้สำเร็จลุล่วง เมื่องานเสร็จสมบูรณ์ไม่ต้องการความช่วยเหลือจากนักแสดงอีกต่อไป เนื่องจากไม่ต้องการความช่วยเหลือผู้ช่วยจึงออกจากสถานที่ ดังนั้นเมื่องานของเธรดที่ไม่ใช่ Daemon จบลงเธรด Daemon ก็จะหายไป


5

เธรด Daemon นั้นเหมือนกับเธรดปกติยกเว้นว่า JVM จะปิดลงเมื่อไม่มีเธรด daemon อื่นเท่านั้นที่ไม่มีอยู่ โดยปกติแล้วเธรด Daemon จะใช้เพื่อดำเนินการบริการสำหรับแอปพลิเคชันของคุณ


5

เธรด Daemon ใน Java เป็นเธรดที่ทำงานในพื้นหลังและส่วนใหญ่สร้างโดย JVM สำหรับการทำงานพื้นหลังเช่นการรวบรวมขยะและงานอื่น ๆ

คะแนนที่ควรทราบ:

  1. เธรดใด ๆ ที่สร้างโดยเธรดหลักซึ่งรันเมธอดหลักใน Java คือโดยดีฟอลต์ไม่ใช่ daemon เนื่องจาก Thread สืบทอดธรรมชาติของ daemon จากเธรดซึ่งสร้างมันขึ้นมาเช่นเธรดหลักและเนื่องจากเธรดหลักเป็นเธรดที่ไม่ใช่ daemon เธรดอื่นใดที่สร้างขึ้นจาก ยังคงไม่ใช่ daemon จนกว่า daemon จะทำอย่างชัดเจนโดยการเรียก setDaemon (จริง)

  2. Thread.setDaemon (true) สร้าง Thread daemon แต่สามารถเรียกใช้ได้ก่อนเริ่ม Thread ใน Java มันจะโยน IllegalThreadStateException หากเธรดที่เกี่ยวข้องนั้นเริ่มต้นและทำงานอยู่

ความแตกต่างระหว่างเธรด Daemon และ Non Daemon ใน Java:

1) JVM ไม่รอเธรด daemon ใด ๆ ให้เสร็จสิ้นก่อนที่จะมีอยู่

2) Daemon Thread ได้รับการปฏิบัติแตกต่างจาก User Thread เมื่อ JVM ยุติลงในที่สุดบล็อกก็จะไม่ถูกเรียกใช้ แต่สแต็กจะไม่ถูกคลายออกและ JVM เพิ่งจะออก


5

ใน Java เธรด Daemonเป็นหนึ่งในประเภทของเธรดซึ่งไม่ได้ป้องกันไม่ให้ Java Virtual Machine (JVM) ออก วัตถุประสงค์หลักของเธรด daemon คือการเรียกใช้งานพื้นหลังโดยเฉพาะในกรณีของงานประจำงวดหรืองานบางอย่าง ด้วยการออกจาก JVM เธรด daemon ก็จะตายเช่นกัน

เมื่อตั้งค่า a thread.setDaemon(true)เธรดจะกลายเป็นเธรด daemon อย่างไรก็ตามคุณสามารถตั้งค่านี้ก่อนที่จะเริ่มด้าย


เธรดชนิดอื่นที่ทำเช่นนั้นคืออะไร? ตอบ: ไม่มี มีเธรด daemon และเธรดที่ไม่ใช่ daemon ระยะเวลา มันเป็นไบนารีสองสถานะ
user207421

5

นี่คือตัวอย่างในการทดสอบพฤติกรรมของเธรด daemon ในกรณีที่ออกจาก jvm เนื่องจากไม่มีเธรดผู้ใช้อยู่

โปรดสังเกตบรรทัดสุดท้ายที่สองในผลลัพธ์ด้านล่างเมื่อเธรดหลักออกแล้วเธรด daemon ก็ตายและไม่ได้พิมพ์คำสั่งที่ถูกเรียกใช้ในที่สุด 9 ในที่สุดบล็อก ซึ่งหมายความว่ารีซอร์ส i / o ใด ๆ ที่ปิดภายในบล็อกสุดท้ายของเธรด daemon จะไม่ถูกปิดหาก JVM ออกจากเนื่องจากไม่มีเธรดผู้ใช้อยู่

public class DeamonTreadExample {

public static void main(String[] args) throws InterruptedException {

    Thread t = new Thread(() -> {
        int count = 0;
        while (true) {
            count++;
            try {
                System.out.println("inside try"+ count);
                Thread.currentThread().sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } finally {
                System.out.println("finally executed"+ count);
            }
        }
    });
    t.setDaemon(true);
    t.start();

    Thread.currentThread().sleep(10000);
    System.out.println("main thread exited");
  }
}

เอาท์พุต

inside try1
finally executed1
inside try2
finally executed2
inside try3
finally executed3
inside try4
finally executed4
inside try5
finally executed5
inside try6
finally executed6
inside try7
finally executed7
inside try8
finally executed8
inside try9
finally executed9
inside try10
main thread exited

4

Daemon เธรดเป็นไปตามที่ทุกคนอธิบายจะไม่ จำกัด JVM ให้ออกดังนั้นโดยทั่วไปแล้วมันเป็นเธรดที่มีความสุขสำหรับ Application จากมุมมองทางออก

ต้องการเพิ่มเธรด daemon ที่สามารถใช้เมื่อพูดว่าฉันกำลังให้ API เช่นการส่งข้อมูลไปยังเซิร์ฟเวอร์บุคคลที่สาม / หรือ JMS ฉันอาจต้องรวบรวมข้อมูลที่ระดับ JVM ของไคลเอ็นต์แล้วส่งไปยัง JMS ในเธรดแยกต่างหาก ฉันสามารถสร้างเธรดนี้เป็น daemon thread ได้หากนี่ไม่ใช่ข้อมูลบังคับที่จะถูกพุชไปยังเซิร์ฟเวอร์ ข้อมูลชนิดนี้เหมือนกับบันทึกการพุช / การรวม

ขอแสดงความนับถือ Manish


นี่เป็นโปรแกรมง่าย ๆ ที่แสดง daemon thread ใน java journaldev.com/1072/java-daemon-thread-example
Pankaj

4

เธรด Daemon เหมือนกับกระบวนการ daemon ซึ่งรับผิดชอบการจัดการทรัพยากรเธรด daemon ถูกสร้างโดย Java VM เพื่อให้บริการเธรดผู้ใช้ ตัวอย่างการอัปเดตระบบสำหรับยูนิกซ์ unix เป็นกระบวนการ daemon child ของ daemon thread เป็น daemon thread เสมอดังนั้นโดย daemon ดีฟอลต์คือ false.you คุณสามารถตรวจสอบ thread เป็น daemon หรือผู้ใช้โดยใช้เมธอด "isDaemon ()" ดังนั้นเธรด daemon หรือกระบวนการ daemon จึงรับผิดชอบการจัดการทรัพยากรโดยทั่วไป ตัวอย่างเช่นเมื่อคุณเริ่ม jvm จะมีตัวรวบรวมขยะที่กำลังรันอยู่ซึ่งเป็น daemon thread ที่มีลำดับความสำคัญเป็น 1 ซึ่งต่ำที่สุดซึ่งกำลังจัดการหน่วยความจำ jvm ยังมีชีวิตอยู่ตราบใดที่เธรดผู้ใช้ยังมีชีวิตอยู่คุณไม่สามารถฆ่า daemon thread.jvm มีความรับผิดชอบในการฆ่าเธรด daemon


สับสนมากและสิ่งเหล่านั้นก็ไม่ใช่ซีเควนต์
user207421

3

ลองพูดในโค้ดพร้อมตัวอย่างการทำงานเท่านั้น ฉันชอบคำตอบของ russ ด้านบน แต่เพื่อลบข้อสงสัยใด ๆ ที่ฉันมีฉันปรับปรุงมันเล็กน้อย ฉันรันสองครั้งครั้งเดียวกับเธรดผู้ทำงานที่ตั้งค่าเป็น deamon true (เธรดเธรด) และอีกครั้งตั้งเป็น false (เธรดผู้ใช้) มันยืนยันว่าเธรด deamon สิ้นสุดลงเมื่อเธรดหลักสิ้นสุดลง

public class DeamonThreadTest {

public static void main(String[] args) {

    new WorkerThread(false).start();    //set it to true and false and run twice.

    try {
        Thread.sleep(7500);
    } catch (InterruptedException e) {
        // handle here exception
    }

    System.out.println("Main Thread ending");
    }
   }

   class WorkerThread extends Thread {

    boolean isDeamon;

    public WorkerThread(boolean isDeamon) {
        // When false, (i.e. when it's a user thread),
        // the Worker thread continues to run.
        // When true, (i.e. when it's a daemon thread),
        // the Worker thread terminates when the main
        // thread terminates.
        this.isDeamon = isDeamon;
        setDaemon(isDeamon);
    }

    public void run() {
        System.out.println("I am a " + (isDeamon ? "Deamon Thread" : "User Thread (none-deamon)"));

        int counter = 0;

        while (counter < 10) {
            counter++;
            System.out.println("\tworking from Worker thread " + counter++);

            try {
                sleep(5000);
            } catch (InterruptedException e) {
                // handle exception here
            }
        }
        System.out.println("\tWorker thread ends. ");
    }
}



result when setDeamon(true)
=====================================
I am a Deamon Thread
    working from Worker thread 0
    working from Worker thread 1
Main Thread ending

Process finished with exit code 0


result when setDeamon(false)
=====================================
I am a User Thread (none-deamon)
    working from Worker thread 0
    working from Worker thread 1
Main Thread ending
    working from Worker thread 2
    working from Worker thread 3
    working from Worker thread 4
    working from Worker thread 5
    working from Worker thread 6
    working from Worker thread 7
    working from Worker thread 8
    working from Worker thread 9
    Worker thread ends. 

Process finished with exit code 0

3

โดยทั่วไปแล้วเธรดภูตจะเรียกว่า "ผู้ให้บริการ" เธรด ไม่ควรใช้เธรดเหล่านี้เพื่อเรียกใช้งานรหัสโปรแกรม แต่เป็นรหัสระบบ เธรดเหล่านี้รันขนานกับโค้ดของคุณ แต่ JVM สามารถฆ่าพวกเขาได้ทุกเมื่อ เมื่อ JVM ไม่พบผู้ใช้เธรดผู้ใช้จะหยุดและเธรด daemon ทั้งหมดจะสิ้นสุดในทันที เราสามารถตั้งค่าเธรดที่ไม่ใช่ daemon เป็น daemon โดยใช้:

setDaemon(true)

3
พวกเขาไม่ได้เป็นที่รู้จักกันโดยทั่วไปว่าเป็น "ผู้ให้บริการ" กระทู้ '
user207421

1
และสามารถใช้เรียกใช้งานโค้ดใด ๆ ได้ JVM ไม่สามารถ 'ฆ่าพวกเขาได้ตลอดเวลา' แต่จะฆ่าพวกเขาเมื่อไม่มีเธรดที่ไม่ใช่ daemon ทำงานอยู่
user207421

@EJP อาจฉันผิด แต่ "มันจะฆ่าพวกเขา" เมื่อเธรดที่ไม่ใช่ daemon ทำงานอยู่ เมื่อเธรดเป็น daemon จะไม่ทำงานโดยแยกการถือ jvm ไว้จนกว่าจะดำเนินการอย่างสมบูรณ์และตอนนี้ได้รับการจัดการที่ระดับ OS
89n3ur0n

มันจะฆ่าพวกเขาเมื่อเธรดที่ไม่ใช่ daemon ทั้งหมดได้ออกและไม่ใช่ picosecond ก่อนหน้านี้ ไม่แน่นอน 'ตลอดเวลา'
user207421

3

เธรด Daemon เป็นเธรดที่ทำงานในพื้นหลังตราบใดที่เธรดที่ไม่ใช่ daemon อื่น ๆ ของกระบวนการยังคงทำงานอยู่ ดังนั้นเมื่อเธรดที่ไม่ใช่ daemon ทั้งหมดเสร็จสมบูรณ์เธรด daemon จะถูกยกเลิก ตัวอย่างสำหรับเธรดที่ไม่ใช่ daemon คือเธรดที่รัน Main เธรดทำ daemon โดยเรียกใช้setDaemon()เมธอดก่อนที่จะเริ่มเธรด

สำหรับการอ้างอิงเพิ่มเติม: เธรดภูตใน Java


2

สำหรับฉันแล้ว daemon thread มันเหมือน house keeper สำหรับเธรดผู้ใช้ หากเธรดผู้ใช้ทั้งหมดเสร็จสิ้นเธรด daemon จะไม่มีงานและถูกฆ่าโดย JVM ผมอธิบายไว้ในวิดีโอ YouTube


2

JVM จะทำงานให้สำเร็จเมื่อการดำเนินการเธรดที่ไม่ใช่ daemon ล่าสุดเสร็จสิ้น โดยค่าเริ่มต้น JVM จะสร้างด้ายเป็น nondaemon แต่เราสามารถทำให้กระทู้เป็น daemon setDaemon(true)ด้วยความช่วยเหลือของวิธีการ ตัวอย่างที่ดีของเธรด Daemon คือเธรด GC ซึ่งจะทำงานให้เสร็จสมบูรณ์ทันทีที่เธรด nondaemon ทั้งหมดเสร็จสมบูรณ์


นั่นเป็นวิธีที่เธรด GC ทำงานอย่างไร การรวบรวมขยะไม่ทำงานแม้ว่าเธรดหลักของโปรแกรมจะใช้เวลานานมาก (เธรดหลักจะไม่ยุติ)
Calicoder

ดังที่ฉันกล่าวถึงเธรด GC จะใช้งานได้จนถึงสิ้นสุดของ NON daemon เธรดสุดท้ายที่จะทำให้การดำเนินการสำเร็จ เธรดหลักของโปรแกรมไม่ใช่ daemon อย่างที่เราทราบดังนั้นเธรด GC จะทำงานได้สำเร็จเมื่อเธรดหลักเสร็จสมบูรณ์ / ถูกฆ่า โดยทั่วไปฉันต้องการจะบอกว่า daemon thread (s) จะถูกยกเลิกเมื่อกระบวนการเสร็จสมบูรณ์และกระบวนการจะเสร็จสมบูรณ์เมื่อมีการเรียกใช้เธรดที่ไม่ใช่ daemon ทั้งหมด
Arman Tumanyan

โดยดีฟอลต์สถานะ daemon ของเธรดจะสืบทอดจากพาเรนต์
user207421

-1

เธรด Daemon จะตายเมื่อเธรดผู้สร้างออก

เธรดที่ไม่ใช่ daemon (ค่าเริ่มต้น) สามารถอยู่ได้นานกว่าเธรดหลัก

if ( threadShouldDieOnApplicationEnd ) {
    thread.setDaemon ( true );
}
thread.start();

นี่เป็นสิ่งที่ผิด มันไม่เกี่ยวกับหัวข้อผู้สร้าง หากมีเธรดใดที่ไม่ใช่ผู้ใช้กำลังทำงานอยู่ daemon เธรดจะยังคงทำงานต่อไป สิ่งนี้สามารถทดสอบได้ง่าย ๆ โดยการสร้างเธรดเบื้องหน้าที่วางเธรด daemon แม้หลังจากเธรดเบื้องหน้าถูกjoinเอ็ด daemon จะยังคงอยู่ตราบเท่าที่เธรดหลักรันอยู่
Hubert Grzeskowiak

เธรด Daemon จะตายเมื่อ JVM ไม่มีเธรดที่ไม่ใช่ daemon ที่รันได้อีกต่อไป ดู Javadoc คำตอบไม่ถูกต้องสมบูรณ์
user207421
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.