笔者在前面几篇文章中详细的讲解了:线程and进程的区别及其各种对比,如何中断一个线程等文章,接下来本篇文章主要讲解:用Java编写代码来等待一个线程join()??
线程之间是并发执行的,操作系统对于线程的调度是无序的,无法判断两个线程谁先执行结束,谁后执行结束~~
我们先来看一个案列吧:顺便猜一下到底是先输入“hello main"还是先输出"hello t”呢??
public class Main {public static void main(String[] args) {Thread t=new Thread(()->{System.out.println("hello t");});t.start();System.out.println("hello main");}
}
那么,我们来看一下该段代码的运行结果:(多次刷新重新运行,会出现不一样的结果)
至于在前面所提到的:猜一下到底是先输入“hello main"还是先输出"hello t”呢??这个是无法确定的~~
该段代码在实际执行的时候,大部分情况下都是先出“hello main"(因为线程的创建也有开销),但是不排除特定情况下,主线程的”hello main“没有立即执行到。程序猿是不喜欢不确定的!!有的时候需要明确规定线程的结束顺序----》可以用线程等待来实现(join()方法)
当我们在上述的代码中加入join()方法以后:
public class Main {public static void main(String[] args) throws InterruptedException {Thread t=new Thread(()->{System.out.println("hello t");});t.start();t.join();//是在main线程中调用t.join()//意思就是让main线程等待t先结束,再往下执行!!别的线程不受影响~System.out.println("hello main");}
}
该段代码的运行结果为:
在上述的代码中,我们再main线程里面加入了join()方法:
t.join();
是在main线程中调用t.join()
意思就是让main线程等待t先结束,再往下执行!!别的线程不受影响~
如果是再t1线程中,加入t2.join(),就是让t1线程等待t2先结束,则t1进入阻塞,其他线程正常调度~
阻塞:Blocking:代码走到这一行就停下来,当前这个线程暂时不参与CPU的调度执行~
在上述的代码中:main阻塞了,不参与CPU的调度了,此时只有t去执行了,单个线程确实也谈不上并发不并发了~
- main线程调用t.join()的时候,如果t还在运行,此时main线程阻塞,直到t执行完毕(t的run()执行完了),main才从阻塞中解除,才继续执行~
- main线程调用t.join()的时候,如果t已经结束了,此时join()不会阻塞,就会立即往下执行
因此,我们可以得出:确保t是先结束的那个~~
其实对于join()还有另外一个版本:可以填写一个参数,作为”起始时间“;
- join()的无参数版本:效果是”死等“(不见不散)~
- join()的有参数版本:则是指定最大超时时间(很常见的设定),如果等待的时间到了上限,还没等到,也就不等了~
- 互相等待《--------》死锁了!Bug~