##不带join,不带daemon:
package hellojava;
import java.util.logging.Level;
import java.util.logging.Logger;
public class HelloJava {
static class TestTask implements Runnable {
private String taskName;
public TestTask(String taskName) {
this.taskName = taskName;
}
@Override
public void run() {
for (int i=0; i<4; i++) {
System.out.println(taskName + ": " + i);
try {
Thread.currentThread().sleep(1*1000);
} catch (InterruptedException ex) {
Logger.getLogger(HelloJava.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
public static void main(String[] args) {
System.out.println("main thread start!");
Thread t1 = new Thread(new HelloJava.TestTask("a"));
Thread t2 = new Thread(new HelloJava.TestTask("b"));
t1.start();
t2.start();
System.out.println("main thread end!");
}
}
运行输出:
main thread start!
a: 0
main thread end!
b: 0
a: 1
b: 1
a: 2
b: 2
a: 3
b: 3
可以看到,t1和t2交替运行,再main线程结束后,t1和、t2仍在运行。
##join
package hellojava;
import java.util.logging.Level;
import java.util.logging.Logger;
public class HelloJava {
static class TestTask implements Runnable {
private String taskName;
public TestTask(String taskName) {
this.taskName = taskName;
}
@Override
public void run() {
for (int i=0; i<4; i++) {
System.out.println(taskName + ": " + i);
try {
Thread.currentThread().sleep(1*1000);
} catch (InterruptedException ex) {
Logger.getLogger(HelloJava.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
public static void main(String[] args){
System.out.println("main thread start!");
Thread t1 = new Thread(new HelloJava.TestTask("a"));
Thread t2 = new Thread(new HelloJava.TestTask("b"));
// t1.setDaemon(true); // 这句注不注释都不影响结果
t1.start();
try {
t1.join();
} catch (InterruptedException ex) {
Logger.getLogger(HelloJava.class.getName()).log(Level.SEVERE, null, ex);
}
t2.start();
System.out.println("main thread end!");
}
}
输出:
main thread start!
a: 0
a: 1
a: 2
a: 3
main thread end!
b: 0
b: 1
b: 2
b: 3
t1运行结束后,t2和main线程才继续运行。注意,只要线程调用join()了,设不设daemon都不影响。
##daemon
package hellojava;
import java.util.logging.Level;
import java.util.logging.Logger;
public class HelloJava {
static class TestTask implements Runnable {
private String taskName;
public TestTask(String taskName) {
this.taskName = taskName;
}
@Override
public void run() {
for (int i=0; i<4; i++) {
System.out.println(taskName + ": " + i);
try {
Thread.sleep(1*1000);
} catch (InterruptedException ex) {
Logger.getLogger(HelloJava.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
public static void main(String[] args){
System.out.println("main thread start!");
Thread t1 = new Thread(new HelloJava.TestTask("a"));
Thread t2 = new Thread(new HelloJava.TestTask("b"));
t1.setDaemon(true);
t2.setDaemon(true);
t1.start();
t2.start();
try {
Thread.sleep(2*1000);
} catch (InterruptedException ex) {
Logger.getLogger(HelloJava.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println("main thread end!");
}
}
输出:
main thread start!
a: 0
b: 0
a: 1
b: 1
main thread end!
b: 2
a: 2
设置daemon后,main线程结束后,daemon线程自动结束并释放。
下面是关于daemon的两个讨论,值得一看:
- How does the JVM terminate daemon threads? or How to write daemon threads that terminate gracefully
- java daemon threads