Daemon Threads ใน Java

1. ภาพรวม

ในบทความสั้น ๆ นี้เราจะดู daemon threads ใน Java และดูว่าใช้ทำอะไรได้บ้าง นอกจากนี้เราจะอธิบายความแตกต่างระหว่างเธรด daemon และเธรดผู้ใช้

2. ความแตกต่างระหว่าง Daemon และ User Threads

Java เสนอเธรดสองประเภท: เธรดผู้ใช้และเธรดดีมอน

เธรดผู้ใช้เป็นเธรดที่มีลำดับความสำคัญสูง JVM จะรอให้เธรดผู้ใช้ทำงานให้เสร็จสิ้นก่อนที่จะยุติ

ในทางกลับกันเธรด daemon เป็นเธรดที่มีลำดับความสำคัญต่ำซึ่งมีบทบาทเพียงอย่างเดียวในการให้บริการแก่เธรดผู้ใช้

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

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

อย่างไรก็ตามมีข้อยกเว้นสำหรับกฎนี้ โค้ดที่ออกแบบมาไม่ดีในเธรด daemon สามารถป้องกันไม่ให้ JVM ออก ตัวอย่างเช่นการเรียกThread.join ()บนเธรด daemon ที่รันอยู่สามารถบล็อกการปิดระบบของแอ็พพลิเคชัน

3. การใช้เธรดภูต

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

4. การสร้าง Daemon Thread

ในการตั้งค่าเธรดให้เป็นเธรด daemon สิ่งที่เราต้องทำคือเรียกใช้Thread.setDaemon () ในตัวอย่างนี้เราจะใช้คลาสNewThreadซึ่งขยายคลาสเธรด :

NewThread daemonThread = new NewThread(); daemonThread.setDaemon(true); daemonThread.start();

เธรดใด ๆ จะสืบทอดสถานะ daemon ของเธรดที่สร้างขึ้น เนื่องจากเธรดหลักเป็นเธรดผู้ใช้เธรดใด ๆ ที่สร้างขึ้นภายในเมธอดหลักจึงเป็นเธรดผู้ใช้โดยดีฟอลต์

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

@Test(expected = IllegalThreadStateException.class) public void whenSetDaemonWhileRunning_thenIllegalThreadStateException() { NewThread daemonThread = new NewThread(); daemonThread.start(); daemonThread.setDaemon(true); }

5. ตรวจสอบว่าเธรดเป็น Daemon Thread หรือไม่

สุดท้ายเพื่อตรวจสอบว่าเธรดเป็นเธรด daemon หรือไม่เราสามารถเรียกเมธอดisDaemon () :

@Test public void whenCallIsDaemon_thenCorrect() { NewThread daemonThread = new NewThread(); NewThread userThread = new NewThread(); daemonThread.setDaemon(true); daemonThread.start(); userThread.start(); assertTrue(daemonThread.isDaemon()); assertFalse(userThread.isDaemon()); }

6. บทสรุป

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

และเช่นเคยโค้ดเวอร์ชันเต็มสามารถใช้ได้บน GitHub