Java多线程之-join方法详解

  • 作用
    • 因为新的线程加入我们,所以我们要等待他执行完再出发
  • 用法
    • main等待thread1执行完毕,主线程等子线程

主线程等待2个子线程运行完毕之后再去运行。主线程流程

public class Join {
    public static void main(String[] args) throws InterruptedException {
        Thread thread1 = new Thread(new Runnable() {
            public void run() {
                try{
                    Thread.sleep(1000);

                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName()+"执行完毕");
            }
        });
        Thread thread2 = new Thread(new Runnable() {
            public void run() {
                try{
                    Thread.sleep(1000);

                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName()+ "执行完毕");
            }
        });

        thread1.start();
        thread2.start();
        System.out.println("开始等待子线程运行完毕");
        //主线程 会等到子线程 运行完毕 再按顺序执行主线程
        thread1.join();
        thread2.join();
        System.out.println("");
    }

}

在这里插入图片描述

主线程 等待join时被打断 就不会再join等待这个子线程继续执行下面的代码 而子线程会继续运行运行 所以主线程遇到中断时 也要对子线程进行中断。

public class JoinInterrupt {
    public static void main(String[] args) {
        final Thread mainThread = Thread.currentThread();
        Thread thread1 = new Thread(new Runnable() {
            public void run() {
                try{
                    //子线程对主线程执行中断
                    mainThread.interrupt();
                    Thread.sleep(1000);

                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName()+"执行完毕");
            }
        });
        thread1.start();
        System.out.println("等待子线程运行完毕");
        try{
            //是主线在等待子线程过程中遇到中断异常
            thread1.join();
        } catch (InterruptedException e) {
        //主线程遇到中断对子线程 也执行中断
            thread1.interrupt();
            System.out.println(Thread.currentThread().getName() +"中断了");
            e.printStackTrace();
        }
        System.out.println("子线程运行完毕");
    }


}

主线程在join是出于waiting状态

public class JoinThreadState {
    public static void main(String[] args) throws InterruptedException {
        final Thread mainthread = Thread.currentThread();
        Thread thread1 = new Thread(new Runnable() {
            public void run() {
                try {
                    Thread.sleep(3000);
                    System.out.println("join时主线程状态"+mainthread.getState());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        thread1.start();
        System.out.println("主线程状态"+mainthread);
        System.out.println("等待子线程运行完毕");
        thread1.join();
        System.out.println("子线程运行完毕");
    }
}

Join注意点

  • CountDownLatch 或 CyclicBarrie类(成熟的工具类)
    Join源码分析 深入join源码会看到 会判断子线程是否结束 没有的话会执行wait()主线程,但是这里只有等待为什么没有唤醒呢?
    在这里插入图片描述
    每个Thread 类会在Run方法运行结束后会自动的notify的操作。
    JVM源码
    在这里插入图片描述

Join等价代码

		//如果能拿到子线程的锁就认为可以解锁
        synchronized (thread1){
            thread1.wait();
        }

面试常见问题

在Join期间,线程会处于什么状态?
Waiting

发布了67 篇原创文章 · 获赞 5 · 访问量 3186

猜你喜欢

转载自blog.csdn.net/weixin_41315492/article/details/103051279