ใครช่วยบอก daemon ว่ามีเธรดอะไรในJavaบ้าง?
ใครช่วยบอก daemon ว่ามีเธรดอะไรในJavaบ้าง?
คำตอบ:
daemon thread เป็นเธรดที่ไม่ป้องกัน JVM จากการออกเมื่อโปรแกรมเสร็จสิ้น แต่เธรดยังคงทำงานอยู่ ตัวอย่างสำหรับเธรด daemon คือการรวบรวมขยะ
คุณสามารถใช้setDaemon(boolean)
วิธีการเปลี่ยนThread
คุณสมบัติ daemon ก่อนที่เธรดจะเริ่มทำงาน
setDamon(boolean)
สามารถเรียกได้ก่อนที่จะเริ่มเธรด โดยดีฟอลต์เธรดจะสืบทอดสถานะ daemon ของเธรดพาเรนต์
thread that does not prevent the JVM from exiting when the program finishes but the thread is still running
โดยทั่วไปหมายถึงกระบวนการ JVM ที่เริ่มเธรดไม่สนใจว่า daemon เธรดดำเนินการเสร็จหรือไม่ก็จะจบลงเองถ้าเธรดปกติทั้งหมดเสร็จสิ้นการดำเนินการ
อีกสองสามคะแนน (การอ้างอิง: Java Concurrency ในทางปฏิบัติ )
เมื่อเธรดที่ไม่ใช่ daemon ทั้งหมดเสร็จสิ้น JVM จะหยุดและเธรด daemonที่เหลือจะถูกทิ้ง :
เนื่องจากเหตุผลนี้จึงควรใช้เธรด daemon อย่างประหยัดและเป็นอันตรายที่จะใช้เธรดเหล่านี้สำหรับงานที่อาจทำ I / O ประเภทใดก็ได้
finally
บล็อกถูกดำเนินการไม่ว่าเธรดนั้นจะเป็น daemon หรือไม่ก็ตาม ดังนั้นอย่าโทรSystem.exit(…)
ถ้าคุณคิดว่าอาจมีกระทู้ที่กำลังทำ I / O อยู่ ข้อแตกต่างเพียงอย่างเดียวคือ JVM จะทริกเกอร์การเลิกจ้างของตนเองเมื่อเหลือ daemon เธรดเท่านั้น
คำตอบข้างต้นทั้งหมดเป็นสิ่งที่ดี นี่คือข้อมูลโค้ดสั้น ๆ ง่ายๆเพื่อแสดงให้เห็นถึงความแตกต่าง ลองใช้กับแต่ละค่าของจริงและเท็จ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
}
}
}
}
โดยปกติแล้วกระบวนการ daemon ใน UNIX นั้นเป็นกระบวนการที่ทำงานอยู่เบื้องหลังเสมอเหมือนบริการใน Windows
เธรด daemon ใน Java เป็นสิ่งที่ไม่ป้องกัน JVM จากการออก โดยเฉพาะ JVM จะออกจากเมื่อ daemon ยังคงอยู่ในเธรดเท่านั้น คุณสามารถสร้างหนึ่งโดยการเรียกวิธีการในการsetDaemon()
Thread
เธรด 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>
กระบวนการพื้นหลังที่จัดการการร้องขอบริการเช่นการเก็บพักงานพิมพ์และการถ่ายโอนไฟล์และหยุดทำงานเมื่อไม่จำเป็น
—— แหล่งที่มา: ภาษาอังกฤษโดยพจนานุกรม Oxford
ด้ายภูตเป็นหัวข้อที่ถือว่าทำงานบางอย่างในพื้นหลังเช่นการจัดการแสดงหรือ chronjobs ต่างๆที่สามารถอยู่ในใบสมัคร
เมื่อโปรแกรมของคุณมีdaemonเหลือเพียงเธรดเท่านั้นโปรแกรมจะออกจากโปรแกรม นั่นเป็นเพราะโดยทั่วไปแล้วเธรดเหล่านี้จะทำงานร่วมกับเธรดปกติและให้การจัดการพื้นหลังของเหตุการณ์
คุณสามารถระบุว่า a Thread
เป็นdaemonโดยใช้setDaemon
วิธีการพวกเขามักจะไม่ออกและไม่ถูกขัดจังหวะ .. พวกเขาจะหยุดเมื่อแอปพลิเคชันหยุด
หนึ่งความเข้าใจผิดที่ฉันต้องการชี้แจง:
Daemon Thread และเธรดผู้ใช้ โดยทั่วไปเธรดทั้งหมดที่สร้างขึ้นโดยโปรแกรมเมอร์คือเธรดผู้ใช้ (เว้นแต่คุณจะระบุว่าเป็น daemon หรือพาเรนต์เธรดของคุณคือเธรด daemon) โดยทั่วไปเธรดผู้ใช้มีความหมายเพื่อเรียกใช้รหัสโปรแกรมของเรา JVM จะไม่ยุติลงเว้นแต่ว่าเธรดผู้ใช้ทั้งหมดจะยุติลง
Java มีเธรดชนิดพิเศษที่เรียกว่าdaemon thread
daemon เธรดใดที่ใช้ทำอะไร
โดยปกติใช้เป็นผู้ให้บริการสำหรับเธรดปกติ โดยทั่วไปจะมีการวนซ้ำไม่สิ้นสุดที่รอคำขอบริการหรือดำเนินการกับเธรด พวกเขาไม่สามารถทำงานที่สำคัญได้ (เพราะเราไม่รู้ว่าเมื่อไหร่ที่พวกเขาจะมีเวลา CPU และพวกเขาสามารถเสร็จสิ้นเมื่อใดก็ได้หากไม่มีเธรดอื่นทำงานอยู่)
ตัวอย่างทั่วไปของชนิดของหัวข้อเหล่านี้เป็นคนเก็บขยะ Java
ยังมีอีก...
setDaemon()
เมธอดก่อนที่จะเรียกใช้start()
เมธอดเท่านั้น เมื่อเธรดกำลังทำงานคุณจะไม่สามารถแก้ไขสถานะ daemon ได้isDaemon()
วิธีการตรวจสอบว่าเธรดเป็นเธรด daemon หรือเธรดผู้ใช้เธรดภูตเป็นเหมือนผู้ช่วย เธรดที่ไม่ใช่ Daemon เป็นเหมือนนักแสดงด้านหน้า ผู้ช่วยช่วยให้นักแสดงสามารถทำงานให้สำเร็จลุล่วง เมื่องานเสร็จสมบูรณ์ไม่ต้องการความช่วยเหลือจากนักแสดงอีกต่อไป เนื่องจากไม่ต้องการความช่วยเหลือผู้ช่วยจึงออกจากสถานที่ ดังนั้นเมื่องานของเธรดที่ไม่ใช่ Daemon จบลงเธรด Daemon ก็จะหายไป
เธรด Daemon นั้นเหมือนกับเธรดปกติยกเว้นว่า JVM จะปิดลงเมื่อไม่มีเธรด daemon อื่นเท่านั้นที่ไม่มีอยู่ โดยปกติแล้วเธรด Daemon จะใช้เพื่อดำเนินการบริการสำหรับแอปพลิเคชันของคุณ
เธรด Daemon ใน Java เป็นเธรดที่ทำงานในพื้นหลังและส่วนใหญ่สร้างโดย JVM สำหรับการทำงานพื้นหลังเช่นการรวบรวมขยะและงานอื่น ๆ
คะแนนที่ควรทราบ:
เธรดใด ๆ ที่สร้างโดยเธรดหลักซึ่งรันเมธอดหลักใน Java คือโดยดีฟอลต์ไม่ใช่ daemon เนื่องจาก Thread สืบทอดธรรมชาติของ daemon จากเธรดซึ่งสร้างมันขึ้นมาเช่นเธรดหลักและเนื่องจากเธรดหลักเป็นเธรดที่ไม่ใช่ daemon เธรดอื่นใดที่สร้างขึ้นจาก ยังคงไม่ใช่ daemon จนกว่า daemon จะทำอย่างชัดเจนโดยการเรียก setDaemon (จริง)
Thread.setDaemon (true) สร้าง Thread daemon แต่สามารถเรียกใช้ได้ก่อนเริ่ม Thread ใน Java มันจะโยน IllegalThreadStateException หากเธรดที่เกี่ยวข้องนั้นเริ่มต้นและทำงานอยู่
ความแตกต่างระหว่างเธรด Daemon และ Non Daemon ใน Java:
1) JVM ไม่รอเธรด daemon ใด ๆ ให้เสร็จสิ้นก่อนที่จะมีอยู่
2) Daemon Thread ได้รับการปฏิบัติแตกต่างจาก User Thread เมื่อ JVM ยุติลงในที่สุดบล็อกก็จะไม่ถูกเรียกใช้ แต่สแต็กจะไม่ถูกคลายออกและ JVM เพิ่งจะออก
ใน Java เธรด Daemonเป็นหนึ่งในประเภทของเธรดซึ่งไม่ได้ป้องกันไม่ให้ Java Virtual Machine (JVM) ออก วัตถุประสงค์หลักของเธรด daemon คือการเรียกใช้งานพื้นหลังโดยเฉพาะในกรณีของงานประจำงวดหรืองานบางอย่าง ด้วยการออกจาก JVM เธรด daemon ก็จะตายเช่นกัน
เมื่อตั้งค่า a thread.setDaemon(true)
เธรดจะกลายเป็นเธรด daemon อย่างไรก็ตามคุณสามารถตั้งค่านี้ก่อนที่จะเริ่มด้าย
นี่คือตัวอย่างในการทดสอบพฤติกรรมของเธรด 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
Daemon เธรดเป็นไปตามที่ทุกคนอธิบายจะไม่ จำกัด JVM ให้ออกดังนั้นโดยทั่วไปแล้วมันเป็นเธรดที่มีความสุขสำหรับ Application จากมุมมองทางออก
ต้องการเพิ่มเธรด daemon ที่สามารถใช้เมื่อพูดว่าฉันกำลังให้ API เช่นการส่งข้อมูลไปยังเซิร์ฟเวอร์บุคคลที่สาม / หรือ JMS ฉันอาจต้องรวบรวมข้อมูลที่ระดับ JVM ของไคลเอ็นต์แล้วส่งไปยัง JMS ในเธรดแยกต่างหาก ฉันสามารถสร้างเธรดนี้เป็น daemon thread ได้หากนี่ไม่ใช่ข้อมูลบังคับที่จะถูกพุชไปยังเซิร์ฟเวอร์ ข้อมูลชนิดนี้เหมือนกับบันทึกการพุช / การรวม
ขอแสดงความนับถือ Manish
เธรด 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
ลองพูดในโค้ดพร้อมตัวอย่างการทำงานเท่านั้น ฉันชอบคำตอบของ 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
โดยทั่วไปแล้วเธรดภูตจะเรียกว่า "ผู้ให้บริการ" เธรด ไม่ควรใช้เธรดเหล่านี้เพื่อเรียกใช้งานรหัสโปรแกรม แต่เป็นรหัสระบบ เธรดเหล่านี้รันขนานกับโค้ดของคุณ แต่ JVM สามารถฆ่าพวกเขาได้ทุกเมื่อ เมื่อ JVM ไม่พบผู้ใช้เธรดผู้ใช้จะหยุดและเธรด daemon ทั้งหมดจะสิ้นสุดในทันที เราสามารถตั้งค่าเธรดที่ไม่ใช่ daemon เป็น daemon โดยใช้:
setDaemon(true)
เธรด Daemon เป็นเธรดที่ทำงานในพื้นหลังตราบใดที่เธรดที่ไม่ใช่ daemon อื่น ๆ ของกระบวนการยังคงทำงานอยู่ ดังนั้นเมื่อเธรดที่ไม่ใช่ daemon ทั้งหมดเสร็จสมบูรณ์เธรด daemon จะถูกยกเลิก ตัวอย่างสำหรับเธรดที่ไม่ใช่ daemon คือเธรดที่รัน Main เธรดทำ daemon โดยเรียกใช้setDaemon()
เมธอดก่อนที่จะเริ่มเธรด
สำหรับการอ้างอิงเพิ่มเติม: เธรดภูตใน Java
สำหรับฉันแล้ว daemon thread มันเหมือน house keeper สำหรับเธรดผู้ใช้ หากเธรดผู้ใช้ทั้งหมดเสร็จสิ้นเธรด daemon จะไม่มีงานและถูกฆ่าโดย JVM ผมอธิบายไว้ในวิดีโอ YouTube
JVM จะทำงานให้สำเร็จเมื่อการดำเนินการเธรดที่ไม่ใช่ daemon ล่าสุดเสร็จสิ้น โดยค่าเริ่มต้น JVM จะสร้างด้ายเป็น nondaemon แต่เราสามารถทำให้กระทู้เป็น daemon setDaemon(true)
ด้วยความช่วยเหลือของวิธีการ ตัวอย่างที่ดีของเธรด Daemon คือเธรด GC ซึ่งจะทำงานให้เสร็จสมบูรณ์ทันทีที่เธรด nondaemon ทั้งหมดเสร็จสมบูรณ์
เธรด Daemon จะตายเมื่อเธรดผู้สร้างออก
เธรดที่ไม่ใช่ daemon (ค่าเริ่มต้น) สามารถอยู่ได้นานกว่าเธรดหลัก
if ( threadShouldDieOnApplicationEnd ) {
thread.setDaemon ( true );
}
thread.start();
join
เอ็ด daemon จะยังคงอยู่ตราบเท่าที่เธรดหลักรันอยู่
Thread
Javadoc อธิบายถึงสิ่งที่พวกเขาจะ: java.sun.com/javase/6/docs/api/java/lang/Thread.html