首先给出结论:t.join()方法只会使主线程进入等待池并等待t线程执行完毕后才会被唤醒。并不影响同一时刻处在运行状态的其他线程。即在t.join方法之前就启动的线程是不受其影响的,t.join只影响当前主线程的执行

一、

分别启动A,B线程,可以看出A线程和B线程是交替执行的。

public class TestJoin {
    public static void main(String[] args) throws InterruptedException {
        ThreadTest t1 = new ThreadTest("A");
        ThreadTest t2 = new ThreadTest("B");
        t1.start();
        t2.start();
    }
}

class ThreadTest extends Thread {
    private String name;
    public ThreadTest(String name){
        this.name=name;
    }

    @Override
    public void run(){
        for(int i=1;i<=5;i++){
            System.out.println(name+"-"+i);
        }
    }
}

运行结果:

B-1
A-1
A-2
A-3
B-2
A-4
B-3
B-4
B-5
A-5

二、

启动线程A,并调用线程A的join方法,会致使当前的main线程进入等待,直到线程A结束生命周期,当前main线程才会往下继续执行;
显然,使用t1.join()之后,main线程继续执行需要等A线程执行完毕之后才能执行,线程B启动,B线程才会执行。需要注意的是,t1.join()需要等t1.start()执行之后执行才有效果,此外,如果t1.join()放在t2.start()之后的话,仍然会是交替执行

public class TestJoin2 {
    public static void main(String[] args) throws InterruptedException {
        // TODO Auto-generated method stub
        ThreadTest t1 = new ThreadTest("A");
        ThreadTest t2 = new ThreadTest("B");
        t1.start();
        //t1执行join方法后,主线程进入等待池并等待t线程执行完毕后才会被唤醒,
        t1.join();
        t2.start();
    }
}

运行结果:

A-1
A-2
A-3
A-4
A-5
B-1
B-2
B-3
B-4
B-5

三、

join()方法只会使主线程进入等待池并等待t线程执行完毕后才会被唤醒。并不影响同一时刻处在运行状态的其他线程。
这里的主线程是main线程,而t2启动在t1的join之前,故t2的执行不受t1的join影响;而主线程main需要等t1,t2线程执行完毕后才可继续往下执行

public class TestJoin3{
    public static void main(String[] args) throws InterruptedException {
        // TODO Auto-generated method stub
        ThreadTest t1 = new ThreadTest("A");
        ThreadTest t2 = new ThreadTest("B");
        t1.start();
        t2.start();,
        t1.join();
        t2.join();
        for (int i=0;i<5;i++){
            System.out.println(Thread.currentThread().getName()+"#"+i);
        }
    }
}

运行结果

A-1
B-1
A-2
A-3
B-2
A-4
A-5
B-3
B-4
B-5
main#0
main#1
main#2
main#3
main#4