join();—->Thread类
    让多个线程同步执行 变成单个线程
    join()方法底层其实是调用了wait()方法
    1.有两个线程 one two two加到one里
    2.设计模型的时候 将two线程在one的run方法里创建 保证两个有先后顺序
    3.two.join();无参数 —-> join(0); 有参数 —-> join(long millis);—->
    if (millis == 0) {//即 join(0);
    while (isAlive()) { //没人调用方法就相当于this.isAlive() 即two对象调 如果two活着
    wait(0); //this.wait(0)—->让别人等着 即访问two对象的线程进入等待状态 即one
    }
    }
    4. one对象只有两个时间点访问到two对象
    1 two想要join的时候
    2 two执行完毕 或 join(millis)中等待的时间到的时候

    线程one:

    1. public class ThreadOne extends Thread{
    2. public void run(){
    3. System.out.println("ThreadOne 执行了");
    4. ThreadTwo two = new ThreadTwo();
    5. two.start();
    6. try {
    7. two.join(2000);//线程2加到线程1中
    8. //join();不带参数的相当于调的是join(long); 即join(0);
    9. //join(2000)即表明one给two的执行时间 若执行比我们的时间长 one会把two踢走 自己继续执行
    10. } catch (InterruptedException e) {
    11. e.printStackTrace();
    12. }
    13. System.out.println("ThreadOne 结束了");
    14. }
    15. }

    线程two:

    1. public class ThreadTwo extends Thread{
    2. public void run(){
    3. System.out.println("two 执行了");
    4. ThreadThree three = new ThreadThree(this);//this就是当前调用run方法的那个two对象
    5. //传进去的two对象就能保证three的run方法锁的是这个two对象
    6. three.start();
    7. try {
    8. Thread.sleep(5000);
    9. } catch (InterruptedException e) {
    10. e.printStackTrace();
    11. }
    12. System.out.println("two 结束了");
    13. }
    14. }

    线程three:

    1. public class ThreadThree extends Thread{
    2. //这里是为了能在run方法中把join到one里执行的那个two对象锁起来
    3. //但是又不能在run方法里new一个two对象 这样就不是同一个two对象了
    4. //而且run方法是重写的 不能传参
    5. //所以只能加属性
    6. private ThreadTwo two;
    7. //调用three的构造方法时 two就有了
    8. public ThreadThree(ThreadTwo two){
    9. this.two = two;
    10. }
    11. public void run(){
    12. System.out.println("three 执行了");
    13. //在two执行的过程中 one等待时 three把two对象锁起来
    14. synchronized (two) {//把线程2锁住了
    15. //即one对象想把two对象踢走时 发现two对象被锁定了 那么one对象只能等待three把two释放
    16. System.out.println("two 被锁了");
    17. try {
    18. Thread.sleep(10000);
    19. } catch (InterruptedException e) {
    20. e.printStackTrace();
    21. }
    22. System.out.println("two自由了");
    23. }
    24. System.out.println("three 执行完毕");
    25. }
    26. }

    主方法:

    1. public static void main(String[] args){
    2. ThreadOne one = new ThreadOne();
    3. one.start();
    4. }