join()函数是Thread类中定义的一个方法,join()的作用是让主线程等待子线程结束之后才能继续进行,简单的示例说明:
- // 主线程
- public class Father extends Thread {
- public void run() {
- Son s = new Son();
- s.start();
- s.join();
- ...
- }
- }
- // 子线程
- public class Son extends Thread {
- public void run() {
- ...
- }
- }
上面有两个类Father类和Son类,并且Son是在Father中创建并启动的,Father是主线程类,Son是子线程类。在Father的主线程中,通过new Son()创建子线程s,接着通过s.start()开启子线程,并调用子线程的s.join()方法,在调用s.join()之后,主线程会一直等到,直到子线程运行完毕。
Thread中join函数源码:
- public final void join() throws InterruptedException
- {
- join(0);
- }
- public final synchronized void join(long millis)throws InterruptedException
- {
- long base = System.currentTimeMillis();
- long now = 0;
- if (millis < 0)
- {
- throw new IllegalArgumentException("timeout value is negative");
- }
- if (millis == 0)
- {
- while (isAlive())
- {
- wait(0);
- }
- }else{
- while (isAlive())
- {
- long delay = millis - now;
- if (delay <= 0) {
- break;
- }
- wait(delay);
- now = System.currentTimeMillis() - base;
- }
- }
- }
- while (isAlive())
- {
- wait(0);
- }
判断当前子线程是活着的那么一直调用wait(0),使主线程处于阻塞状态。我们之前在线程等待中说到过,wait()的作用是让当前线程等待,当前线程就是指当前在CPU上运行的线程。虽然是调用子线程的wait()方法,但它是通过主线程去调用的,所以休眠的是主线程而不是子线程。
join()方法简单示例:
- public class JoinTest{
- public static void main(String[] args){
- try {
- ThreadA t1 = new ThreadA("t1"); // 新建“线程t1”
- t1.start(); // 启动“线程t1”
- t1.join(); // 将“线程t1”加入到“主线程main”中,并且“主线程main()会等待它的完成”
- System.out.printf("%s finish\n", Thread.currentThread().getName());
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- static class ThreadA extends Thread{
- public ThreadA(String name){
- super(name);
- }
- public void run(){
- System.out.printf("%s start\n", this.getName());
- // 延时操作
- for(int i=0; i <1000000; i++);
- System.out.printf("%s finish\n", this.getName());
- }
- }
- }
运行结果:
t1 start
t1 finish
main finish