【Java】【多线程】线程的方法join
学而不思则罔,思而不学则殆
join简单范例
jion某个线程,会使当前线程进入等待,直到线程A结束生命周期或者达到给定的时间,那么在此当前线程出图BLOACKED的。
private static void testJoin() {
Thread threadA = new Thread(new Runnable() {
@Override
public void run() {
try {
System.out.println(Thread.currentThread().getName() + " sleep");
TimeUnit.MINUTES.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
threadA.setName("test_join");
threadA.setDaemon(true);
threadA.start();
try {
System.out.println("join threadA");
threadA.join();//等待threadA结束
} catch (InterruptedException e) {
e.printStackTrace();
}
}
main线程等待threadA结束,threadA线程睡眠10分钟。
通过jconsole.exe和jstack等命令查看此时线程状态:
main线程状态
可以看到main线程在调用join方法,等待test_join结束,最终调用的是wait方法。线程状态是【WAITING】
test_join线程状态
test_join线程处于【TIMED_WAITING】
join范例一 - 有join和没有join的结果
private static void testJoin2() {
Thread threadA = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 5; i++) {
try {
TimeUnit.MILLISECONDS.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " " + i);
}
}
});
threadA.setName("test_join");
threadA.setDaemon(true);
threadA.start();
// try {
// System.out.println("join threadA");
// threadA.join();//等待threadA结束
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
for (int i = 0; i < 5; i++) {
try {
TimeUnit.MILLISECONDS.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " " + i);
}
}
没有join的结果:
main 0
test_join 0
test_join 1
main 1
test_join 2
main 2
test_join 3
main 3
test_join 4
main 4
两个线程交替输出
打开注释的结果:
join threadA
test_join 0
test_join 1
test_join 2
test_join 3
test_join 4
main 0
main 1
main 2
main 3
main 4
当执行join方法后。main线程会等待test_join 线程执行完过后才会输出。
测试范例二
等待指定时间后还没有结束就不在等待
private static void testJoin3() {
Thread threadA = new Thread(new Runnable() {
@Override
public void run() {
try {
System.out.println(Thread.currentThread().getName() + " sleep 10min");
TimeUnit.MINUTES.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
threadA.setName("test_join");
threadA.setDaemon(true);
threadA.start();
try {
System.out.println("join start threadA " + System.currentTimeMillis());
threadA.join(1000 * 10);//等待threadA结束或者10秒没结束也就不再等待
System.out.println("join end threadA " + System.currentTimeMillis());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
join start threadA 1599282349237
test_join sleep 10min
join end threadA 1599282359238
等待threadA结束或者10秒没结束也就不再等待,可见10秒就结束等待了。
测试范例三
等待指定时间内线程结束,退出等待
private static void testJoin3() {
Thread threadA = new Thread(new Runnable() {
@Override
public void run() {
try {
System.out.println(Thread.currentThread().getName() + " start sleep " + System.currentTimeMillis());
TimeUnit.SECONDS.sleep(2);
System.out.println(Thread.currentThread().getName() + " end sleep " + System.currentTimeMillis());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
threadA.setName("test_join");
threadA.setDaemon(true);
threadA.start();
try {
System.out.println("join start threadA " + System.currentTimeMillis());
threadA.join(1000 * 10);//等待threadA结束或者10秒没结束也就不再等待
System.out.println("join end threadA " + System.currentTimeMillis());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
join start threadA 1599282615331
test_join start sleep 1599282615333
test_join end sleep 1599282617334
join end threadA 1599282617334
test_join 线程结束,main线程也结束等待。