Ai đó có thể cho tôi biết các chủ đề daemon trong Java không?
Ai đó có thể cho tôi biết các chủ đề daemon trong Java không?
Câu trả lời:
Một luồng daemon là một luồng không ngăn JVM thoát khi chương trình kết thúc nhưng luồng vẫn chạy. Một ví dụ cho một chủ đề daemon là bộ sưu tập rác.
Bạn có thể sử dụng setDaemon(boolean)
phương thức để thay đổi các Thread
thuộc tính daemon trước khi luồng bắt đầu.
setDamon(boolean)
chỉ có thể được gọi trước khi chủ đề đã được bắt đầu. Theo mặc định, luồng kế thừa trạng thái daemon của luồng gốc.
thread that does not prevent the JVM from exiting when the program finishes but the thread is still running
về cơ bản có nghĩa là quá trình JVM bắt đầu luồng không quan tâm nếu luồng daemon kết thúc thực thi hay không, nó sẽ tự kết thúc nếu tất cả các luồng bình thường đã thực hiện xong.
Một vài điểm nữa (Tham khảo: Thực hành đồng thời Java )
Khi tất cả các luồng không phải daemon kết thúc, JVM tạm dừng và mọi luồng daemon còn lại sẽ bị hủy :
Vì lý do này, các chủ đề daemon nên được sử dụng một cách tiết kiệm và thật nguy hiểm khi sử dụng chúng cho các tác vụ có thể thực hiện bất kỳ loại I / O nào.
finally
khối nào được thực thi, bất kể các luồng có phải là daemon hay không. Vì vậy, đừng gọi System.exit(…)
nếu bạn nghĩ rằng có thể có các luồng đang chạy I / O. Sự khác biệt duy nhất là JVM sẽ kích hoạt sự chấm dứt của chính nó khi chỉ còn lại các luồng daemon.
Tất cả các câu trả lời trên là tốt. Đây là một đoạn mã nhỏ đơn giản, để minh họa cho sự khác biệt. Hãy thử nó với từng giá trị đúng và sai trong 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
}
}
}
}
Các quy trình daemon truyền thống trong UNIX là các quy trình liên tục chạy trong nền, giống như các dịch vụ trong Windows.
Một luồng daemon trong Java là một luồng không ngăn JVM thoát. Cụ thể, JVM sẽ thoát khi chỉ còn các luồng daemon. Bạn tạo một cái bằng cách gọi setDaemon()
phương thức trên Thread
.
Các luồng Daemon giống như một nhà cung cấp dịch vụ cho các luồng hoặc đối tượng khác đang chạy trong cùng tiến trình với luồng daemon. Các luồng Daemon được sử dụng cho các tác vụ hỗ trợ nền và chỉ cần thiết trong khi các luồng thông thường đang thực thi. Nếu các luồng thông thường không chạy và các luồng còn lại là các luồng daemon thì trình thông dịch sẽ thoát.
Ví dụ: trình duyệt HotJava sử dụng tối đa bốn luồng daemon có tên "Trình tải hình ảnh" để tìm nạp hình ảnh từ hệ thống tệp hoặc mạng cho bất kỳ luồng nào cần một luồng.
Các luồng Daemon thường được sử dụng để thực hiện các dịch vụ cho ứng dụng / applet của bạn (chẳng hạn như tải "bit fiddley"). Sự khác biệt cốt lõi giữa các luồng người dùng và luồng daemon là JVM sẽ chỉ tắt một chương trình khi tất cả các luồng người dùng đã kết thúc. Các luồng Daemon bị JVM chấm dứt khi không còn bất kỳ luồng người dùng nào đang chạy, bao gồm cả luồng thực thi chính.
setDaemon (đúng / sai)? Phương pháp này được sử dụng để xác định rằng một luồng là luồng daemon.
boolean isDaemon ()? Phương pháp này được sử dụng để xác định luồng có phải là luồng daemon hay không.
Ví dụ:
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");
}
}
Ra ngoài:
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>
Một quy trình nền xử lý các yêu cầu cho các dịch vụ như in đệm và truyền tệp và không hoạt động khi không cần thiết.
Nguồn của Dick Nguồn: Tiếng Anh của Từ điển Oxford
Một chủ đề daemon là một chủ đề được coi là thực hiện một số tác vụ trong nền như xử lý các yêu cầu hoặc các chronjob khác nhau có thể tồn tại trong một ứng dụng.
Khi chương trình của bạn chỉ còn các chủ đề daemon, nó sẽ thoát. Đó là bởi vì thông thường các luồng này hoạt động cùng với các luồng bình thường và cung cấp xử lý nền cho các sự kiện.
Bạn có thể chỉ định rằng a Thread
là một daemon bằng cách sử dụng setDaemon
phương thức, chúng thường không thoát, chúng không bị gián đoạn .. chúng chỉ dừng khi ứng dụng dừng.
Một quan niệm sai lầm tôi muốn làm rõ:
Chủ đề Daemon và chủ đề người dùng. Nói chung tất cả các luồng được tạo bởi lập trình viên là luồng người dùng (trừ khi bạn chỉ định nó là daemon hoặc luồng gốc của bạn là luồng daemon). Chủ đề người dùng thường có nghĩa là để chạy mã chương trình của chúng tôi. JVM không chấm dứt trừ khi tất cả các luồng người dùng chấm dứt.
Java có một loại luồng đặc biệt gọi là luồng daemon .
Chủ đề daemon được sử dụng để làm gì?
Thường được sử dụng như nhà cung cấp dịch vụ cho chủ đề bình thường. Thường có một vòng lặp vô hạn chờ yêu cầu dịch vụ hoặc thực hiện các nhiệm vụ của luồng. Họ không thể làm những công việc quan trọng. (Bởi vì chúng tôi không biết khi nào họ sẽ có thời gian CPU và họ có thể hoàn thành bất cứ lúc nào nếu không có bất kỳ luồng nào khác đang chạy.)
Một ví dụ điển hình của các loại luồng này là trình thu gom rác Java .
Còn nữa...
setDaemon()
phương thức trước khi bạn gọi start()
phương thức. Khi luồng đang chạy, bạn không thể sửa đổi trạng thái trình nền của nó.isDaemon()
phương pháp để kiểm tra xem một luồng là một luồng daemon hay một luồng người dùng.Chủ đề Daemon giống như trợ lý. Chủ đề không phải Daemon giống như người biểu diễn phía trước. Trợ lý giúp người biểu diễn hoàn thành công việc. Khi công việc hoàn thành, người biểu diễn không cần sự giúp đỡ để thực hiện nữa. Vì không cần giúp đỡ nên các trợ lý rời khỏi nơi này. Vì vậy, khi công việc của các chủ đề Non-Daemon kết thúc, các chủ đề Daemon sẽ diễu hành.
Chủ đề Daemon trong Java là các luồng chạy trong nền và chủ yếu được tạo bởi JVM để thực hiện các tác vụ nền như bộ sưu tập Rác và các tác vụ giữ nhà khác.
Điểm cần lưu ý :
Bất kỳ luồng nào được tạo bởi luồng chính, chạy phương thức chính trong Java theo mặc định là không phải daemon vì Thread thừa hưởng bản chất daemon của nó từ luồng tạo ra nó tức là luồng gốc và vì luồng chính là luồng không daemon, nên bất kỳ luồng nào khác được tạo từ nó sẽ vẫn không phải daemon cho đến khi daemon được tạo rõ ràng bằng cách gọi setDaemon (true).
Thread.setDaemon (true) tạo một daemon Thread nhưng nó chỉ có thể được gọi trước khi bắt đầu Thread trong Java. Nó sẽ ném IllegalThreadStateException nếu Thread tương ứng đã được bắt đầu và chạy.
Sự khác biệt giữa luồng Daemon và Non Daemon trong Java:
1) JVM không đợi bất kỳ luồng daemon nào kết thúc trước khi tồn tại.
2) Chủ đề Daemon được xử lý khác với Chủ đề người dùng khi JVM chấm dứt, cuối cùng các khối không được gọi, Ngăn xếp không được giải quyết và JVM chỉ tồn tại.
Trong Java, Chủ đề Daemon là một trong những loại luồng không ngăn Máy ảo Java (JVM) thoát. Mục đích chính của luồng daemon là thực thi tác vụ nền, đặc biệt trong trường hợp một số tác vụ hoặc công việc định kỳ thông thường. Với lối ra JVM, luồng daemon cũng chết.
Bằng cách đặt a thread.setDaemon(true)
, một chủ đề trở thành một chủ đề daemon. Tuy nhiên, bạn chỉ có thể đặt giá trị này trước khi bắt đầu chuỗi.
Dưới đây là một ví dụ để kiểm tra hành vi của các luồng daemon trong trường hợp thoát jvm do không tồn tại các luồng của người dùng.
Xin lưu ý dòng cuối cùng thứ hai trong đầu ra dưới đây, khi chủ đề chính đã thoát, daemon thread cũng chết và không in cuối cùng executed9 tuyên bố trong khối finally. Điều này có nghĩa là bất kỳ tài nguyên i / o nào được đóng trong khối cuối cùng của luồng daemon sẽ không bị đóng nếu JVM thoát do không tồn tại các luồng của người dùng.
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
Các luồng Daemon như mọi người đã giải thích, sẽ không hạn chế JVM để thoát, vì vậy về cơ bản, đây là một luồng hạnh phúc cho Ứng dụng theo quan điểm thoát.
Muốn thêm các luồng daemon có thể được sử dụng khi nói rằng tôi đang cung cấp API như đẩy dữ liệu lên máy chủ của bên thứ 3 / hoặc JMS, tôi có thể cần tổng hợp dữ liệu ở cấp JVM của máy khách và sau đó gửi đến JMS trong một luồng riêng biệt. Tôi có thể tạo chủ đề này dưới dạng chủ đề daemon, nếu đây không phải là dữ liệu bắt buộc được đẩy lên máy chủ. Loại dữ liệu này giống như đẩy / tổng hợp nhật ký.
Trân trọng, Manish
Chuỗi daemon giống như tiến trình daemon chịu trách nhiệm quản lý tài nguyên, luồng daemon được Java VM tạo ra để phục vụ các luồng người dùng. ví dụ hệ thống cập nhật cho unix, unix là quá trình daemon. con của luồng daemon luôn là luồng daemon, do đó, mặc định daemon là false. Bạn có thể kiểm tra luồng như daemon hoặc người dùng bằng cách sử dụng phương thức "isDaemon ()". vì vậy chủ đề daemon hoặc quá trình daemon chịu trách nhiệm cơ bản để quản lý tài nguyên. ví dụ: khi bạn bắt đầu jvm, có trình thu gom rác đang chạy là luồng daemon có mức ưu tiên là 1 thấp nhất, đó là quản lý bộ nhớ. jvm vẫn tồn tại miễn là luồng người dùng còn sống, bạn không thể giết daemon thread.jvm chịu trách nhiệm giết các luồng daemon.
Chúng ta chỉ nói chuyện bằng mã với các ví dụ làm việc. Tôi thích câu trả lời của Nga ở trên nhưng để xóa bỏ mọi nghi ngờ tôi có, tôi đã tăng cường thêm một chút. Tôi đã chạy nó hai lần, một lần với luồng công nhân được đặt thành deamon true (luồng deamon) và lần khác đặt nó thành false (luồng người dùng). Nó xác nhận rằng luồng deamon kết thúc khi luồng chính kết thúc.
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
Chủ đề Daemon thường được gọi là chủ đề "Nhà cung cấp dịch vụ". Các luồng này không nên được sử dụng để thực thi mã chương trình mà là mã hệ thống. Các luồng này chạy song song với mã của bạn nhưng JVM có thể giết chúng bất cứ lúc nào. Khi JVM không tìm thấy các luồng người dùng, nó dừng nó và tất cả các luồng daemon chấm dứt ngay lập tức. Chúng ta có thể đặt luồng không phải daemon thành daemon bằng cách sử dụng:
setDaemon(true)
Chủ đề Daemon là các chủ đề chạy trong nền miễn là các chủ đề không phải trình nền khác của quy trình vẫn đang chạy. Do đó, khi tất cả các luồng không phải daemon hoàn thành, các luồng daemon bị chấm dứt. Một ví dụ cho luồng không phải daemon là luồng chạy Main. Một luồng được tạo daemon bằng cách gọi setDaemon()
phương thức trước khi luồng được bắt đầu
Để tham khảo thêm: Chủ đề Daemon trong Java
Đối với tôi, chủ đề daemon giống như người quản lý nhà cho chủ đề người dùng. Nếu tất cả các luồng người dùng kết thúc, luồng daemon không có công việc và bị JVM giết. Tôi đã giải thích nó trong video YouTube .
JVM sẽ hoàn thành công việc khi việc thực thi luồng không phải daemon cuối cùng được hoàn thành. Theo mặc định, JVM sẽ tạo một luồng như nondaemon nhưng chúng ta có thể tạo Thread như một daemon với sự trợ giúp của phương thức setDaemon(true)
. Một ví dụ điển hình của luồng Daemon là luồng GC sẽ hoàn thành công việc của anh ta ngay khi tất cả các luồng nondaemon được hoàn thành.
Chủ đề Daemon chết khi chủ đề của người tạo thoát ra.
Các chủ đề không phải daemon (mặc định) thậm chí có thể sống lâu hơn các chủ đề chính.
if ( threadShouldDieOnApplicationEnd ) {
thread.setDaemon ( true );
}
thread.start();
join
ed, daemon sẽ vẫn duy trì miễn là chủ đề chính chạy.
Thread
javadoc mô tả những gì họ đang: java.sun.com/javase/6/docs/api/java/lang/Thread.html