在Java有两种线程一个是主线程一个是守护线程。而setDaemon()方法就是将当前线程设置为守护线程的方法。守护线程的特点就是当主线程结束时,守护线程自动终止。我们通过下面的例子演示这个效果。
/**
* 消息生产者
*
* @author Sama
* @author admin@jilinwula.com
* @date 2017-03-13 16:31
* @since 1.0.0
*/
public class MessageServer implements Runnable {
@Override
public void run() {
for (int i = 1; i <= 20; i++) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName());
}
}
}
/**
* 消息消费者
*
* @author Sama
* @author admin@jilinwula.com
* @date 2017-03-13 16:41
* @since 1.0.0
*/
public class MessageClient {
public static void main(String[] args) throws InterruptedException {
MessageServer messageServer = new MessageServer();
Thread thread = new Thread(messageServer);
thread.setDaemon(true);
thread.start();
Thread.sleep(1000);
System.out.println("主线程停止");
}
}
Thread-0
主线程停止
Thread-0
我们看输出信息得知。虽然我们没有在循环中添加任何让线程停止的代码,但线程明显示没有执行完就自动停止了,这就是因为主线程停止了,所以守护线程也就没什么存在的必要了。最典型的守护线程就是Java的垃圾回收器的线程了。这里有一个需要特别注意的地方就是设置守护线程必须在线程没有开启时设置。也就是说必须要在start()方法之前设置。否则该线程不但不能设置为守护线程,Jvm还会抛出异常信息。
/**
* 消息生产者
*
* @author Sama
* @author admin@jilinwula.com
* @date 2017-03-13 16:31
* @since 1.0.0
*/
public class MessageServer implements Runnable {
@Override
public void run() {
for (int i = 1; i <= 20; i++) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(String.format("i: %s thread: %s", i, Thread.currentThread().getName()));
}
}
}
/**
* 消息消费者
*
* @author Sama
* @author admin@jilinwula.com
* @date 2017-03-13 16:41
* @since 1.0.0
*/
public class MessageClient {
public static void main(String[] args) throws InterruptedException {
MessageServer messageServer = new MessageServer();
Thread thread = new Thread(messageServer);
thread.start();
thread.setDaemon(true);
Thread.sleep(1000);
System.out.println("主线程停止");
}
}
Exception in thread "main" java.lang.IllegalThreadStateException
at java.lang.Thread.setDaemon(Thread.java:1352)
at MessageClient.main(MessageClient.java:14)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
i: 1 thread: Thread-0
i: 2 thread: Thread-0
i: 3 thread: Thread-0
i: 4 thread: Thread-0
i: 5 thread: Thread-0
i: 6 thread: Thread-0
i: 7 thread: Thread-0
i: 8 thread: Thread-0
i: 9 thread: Thread-0
i: 10 thread: Thread-0
i: 11 thread: Thread-0
i: 12 thread: Thread-0
i: 13 thread: Thread-0
i: 14 thread: Thread-0
i: 15 thread: Thread-0
i: 16 thread: Thread-0
i: 17 thread: Thread-0
i: 18 thread: Thread-0
i: 19 thread: Thread-0
i: 20 thread: Thread-0