1. Daemon Thread và User Thread trong Java
Trong Java, có 2 lọai Thread là:
– Daemon Thread
– User Thread còn gọi là Non-Daemon Thread
Daemon Thread là một Thread có độ ưu tiên thấp, thường dùng để chạy các dịch vụ nền như Garbage Collection (GC). Daemon Thread trong Java thường là những Thread cung cấp dịch vụ cho User Thread. Khi tất cả các User Thread kết thúc thì JVM sẽ tự động kết thúc Daemon Thread. Bảng bên dưới chỉ ra sự khác nhau giữa Daemon Thread và User Thread.User Thread Daemon Thread JVM luôn chờ cho đến khi User Thread thực thi xong tất cả các công việc của nó. JVM không bao giờ kết thúc đột ngột một User Thread (trừ trường hợp xảy ra ngoại lệ – exception) JVM sẽ kế thúc Daemon Thread khi tất cả User Thread thực thi xong. JVM sẽ không cần chờ Daemon Thread hoàn thành xong công việc của nó. User Thread được tạo ra bởi lập trình viên viết ứng dụng. Hầu hết Daemon Thread được tạo ra bởi JVM. User Thread được tạo ra để thực hiện một công việc cụ thể nào đó. Daemon Thread được tạo ra để phục vụ User Thread. User Thread còn gọi là foreground thread. Daemon Thread còn gọi là background thread. User Thread có độ ưu tiên cao, cần được đưa và CPU để xử lý trước. Daemon Thread có độ ưu tiên thấp. Vòng đời của User Thread là hoàn toàn độc lập, phụ thuộc vào công việc mà nó thực thi. Vòng đời của Daemon Thread phụ thuộc vào User Thread.
Bình thường tất cả các Thread do lập trình viên tạo ra trong ứng dụng đều là User Thread. Còn các Daemon Thread chủ yếu do JVM tạo ra. Nhưng chúng ta cũng có thể thiết lập một Thread là Daemon Thread với hàm void setDaemon(boolean on)
. Nếu boolean on
là true thì đánh dấu Thread là Daemon Thread.
Để kiểm tra một Thread có phải là Daemon Thread hay không thì chúng ta dùng hàm boolean isDaemon(
).
2. Ví dụ về Daemon Thread và User Thread trong Java
Kiểm tra một Thread có phải là Daemon Thread hay không?
class MyThread extends Thread {
@Override
public void run(){
System.out.println("MyThread working...");
}
}
class Main {
public static void main(String[] args){
MyThread mt = new MyThread();
mt.setName("MyThread");
mt.start();
System.out.println("Main Thread");
System.out.println("Is " + mt.getName()
+ " a Daemon Thread: "
+ mt.isDaemon());
System.out.println("Is " + Thread.currentThread().getName()
+ " a Daemon Thread: "
+ Thread.currentThread().isDaemon());
}
}
Kết quả
Main Thread
MyThread working...
Is MyThread a Daemon Thread: false
Is main a Daemon Thread: false
Trong ví dụ trên, có 2 Thread được thực thi là:
- Thread main: tự động được tạo ra và có nhiệm vụ tìm hàm main() để thực thi.
- Thread MyThread: được tạo ra bởi lập trình viên và thực thi khi gọi hàm start()
Cả 2 Thread trên đều không phải là Daemon Thread.
Tạo một Daemon Thread
class MyThread extends Thread {
@Override
public void run(){
System.out.println("Non-Daemon thread");
}
}
class Main {
public static void main(String[] args){
MyThread mt = new MyThread();
mt.setName("MyThread");
System.out.println("Before using setDaemon() method: ");
System.out.println("Is " + mt.getName()
+ " a Daemon Thread: "
+ mt.isDaemon());
mt.setDaemon(true);
System.out.println("After using setDaemon() method: ");
System.out.println("Is " + mt.getName()
+ " a Daemon Thread: "
+ mt.isDaemon());
mt.start();
}
}
Kết quả
Before using setDaemon() method:
Is MyThread a Daemon Thread: false
After using setDaemon() method:
Is MyThread a Daemon Thread: true
Trong ví dụ trên, chúng ta sử dụng hàm setDaemon(boolean on)
để đánh dấu MyThread là một Daemon Thread.
Khi User Thread kết thúc thì JVM cũng kết thúc Daemon Thread
class MyThread extends Thread {
@Override
public void run(){
while (true) {
processSomething();
}
}
private void processSomething() {
try {
System.out.println("MyThread processing...");
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class Main {
public static void main(String[] args) throws InterruptedException{
MyThread mt = new MyThread();
mt.setName("MyThread");
mt.setDaemon(true);
mt.start();
//continue program
Thread.sleep(3000);
System.out.println("main thread finished!");
}
}
Kết quả
MyThread processing...
MyThread processing...
MyThread processing...
MyThread processing...
MyThread processing...
MyThread processing...
main thread finished!
Trong ví dụ trên, chúng ta tạo ra một MyThread thực thi với vòng lặp vô tận while(true)
. Tức là, bình thường MyThread là một User Thread nên một khi được start()
thì sẽ thực thi mãi mãi bất kể main Thread thực thi xong hay chưa.
Nhưng nếu chúng ta đánh dấu MyThread là một Daemon Thread thì nó sẽ được kết thúc khi main Thread kết thúc.