Thread中join的作用和原理

文章介绍内容
  1. Thread.join 作用
  2. Thread.join的实现原理
  3. 什么时候会使用Thread.join
  4. 扩展

1作用

当多线程情况每个单线程都在竞争获取cpu执行权,顺序是先得先折行,先为保证子线程执行顺序,通过Thread.join 控制主线程让子线程执行完再执行下一个子线程,底部实现原理使用Object中wait

dome1


public class ThreadJoin {

    static Thread thread1=new Thread(new Runnable() {
        @Override
        public void run() {
            System.out.println("thread1");
        }
    });
    static Thread thread2=new Thread(new Runnable() {
        @Override
        public void run() {
            System.out.println("thread2");
        }
    });
    static Thread thread3=new Thread(new Runnable() {
        @Override
        public void run() {
            System.out.println("thread3");
        }
    });

    public static void main(String[] args) throws InterruptedException {
        thread1.run();
        thread1.join();
        thread2.run();
        thread1.join();
        thread3.run();
        thread3.join();
    }

}

执行结果 :

thread1
thread2
thread3

Process finished with exit code 0

显现:
当代码中不加 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;
            }
        }
    }

总结:当主线程调用run子线程,子线程调用join,会对主线程进行阻塞通过join源码可以看出synchronized , wait()方法等待执行完再执行主线程执行第二个子线程,保证每一个线程的执行完再执行下一个子线程

什么时候是使用

当多线程情况下需要,列如:t1,t2线程,在执行t1时需要t1的结果进行其他业务逻辑是可以采用Thread.join等待子线程执行完再做下面逻辑操作
具体参考deom2

public void joinDemo(){
   //....
   Thread t=new Thread(payService);
   t.start();
   //.... 
   //其他业务逻辑处理,不需要确定t线程是否执行完
   insertData();
   //后续的处理,需要依赖t线程的执行结果,可以在这里调用join方法等待t线程执行结束
   t.join();
}

扩展

我们还可以通过多线程队里FIFO方式达到顺序执行过程
思路,通过线程池Executors.newSingleThreadExecutor() 单线程模式里,底层使用FIFO(先进先出)实现多线程有序执行

参考dome1修改

 ExecutorService executorService=Executors.newSingleThreadExecutor();
        executorService.execute( thread1);
        executorService.execute( thread2);
        executorService.execute( thread3);
        executorService.isShutdown();

输出结果一致

有理解不恰当地方欢迎吐槽~~

发布了10 篇原创文章 · 获赞 9 · 访问量 447

猜你喜欢

转载自blog.csdn.net/weixin_43829047/article/details/104903154