public static void main(String[] args) throws Exception{
Thread t1 = new Thread(() -> {
for (int i = 0; i < 10; i++) {
System.out.println("i = " + i);
}
});
t1.start();
t1.join();
System.out.println("main end");
}
main线程要等到t1线程运行结束后,才会输出“main end”。如果不加t1.join(),main线程和t1线程是并行的。而加上t1.join(),程序就变成是顺序执行了。我们在用到join()的时候,通常都是main线程等到其他多个线程执行完毕后再继续执行,即main被挂起。而其他多个线程之间并不需要互相等待
下面是一个例子:
package cn.cuit.stream;
public class MyJava8Interface01{
public static void main(String[] args) throws Exception {
MyRunable myRunable1 = new MyRunable();
MyRunable myRunable2 = new MyRunable();
Thread thread1 = new Thread(myRunable1, "Thread1");
Thread thread2 = new Thread(myRunable2, "Thread2");
// join的位置和线程start的位置也是相关的,看下面的举例分析
/**
* thread1.start();
thread2.start();
* 当t1和t2都不join,这是main和t1、t2三者是并行运行的,所以输出结果大体是三者交替输出
*/
/**
* thread1.start();
thread1.join();
thread2.start();
* 当t1 join时,此时main挂起,t1执行完后main才恢复,而t2此时还没start,因为main已经挂起不向下执行了,所以输出结果大体是t1完全输出,t2和main交替输出
*/
/**
* thread1.start();
thread2.start();
thread2.join();
当t2 join,此时t1和t2都已启动,main挂起,所以大体输出结果是t1和t2交替输出,main完整输出
*/
/**
* thread1.start();
thread1.join();
thread2.start();
thread2.join();
* 当t1和t2都join,但是注意join的位置,效果是t1完整输完,后t2完整输出,然后main完整输出
*/
/**
* thread1.start();
thread2.start();
thread1.join();
thread2.join();
* 当t1和t2都join,但是注意join的位置,输出结果大体是t1和t2会交替执行,如果t1肯定没输出完main肯定不会执行,但是t2就不一样,如果t1更快的结束,t2还有很多没执行完,那么join时,就会先全部输出t2,然后在是全部输出main,总之main肯定是完整输出
*/
// 通过上面多个例子的解析和输出,join方法的用途也就差不多整懂了,就是让当前线程执行,即调用join方法的线程执行【叫做被调用线程】,
// 而调用join这个方法的线程实例的所在的线程将被挂起【简单理解就是这个线程实例.join的代码写在哪个线程中,哪个线程就被挂起】,
// 这里是main线程【那么main现在就是调用线程,即在main中有线程调用了join】
// 即在main现在中t1线程调用join,那么main就被t1挂起了,直到t1执行完,main才恢复执行
thread1.start();
thread2.start();
thread1.join();
thread2.join();
System.out.println("Thread.currentThread > "+ Thread.currentThread().getName());
for (int i = 0; i < 1000; i++) {
Thread.sleep(10);
System.out.println(Thread.currentThread().getName() +" > "+ i);
}
}
}
class MyRunable implements Runnable {
@Override
public void run() {
for (int i = 0; i < 1000; i++) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() +" > "+ i);
}
}
}
总结: join方法当我们调用某个线程的这个方法时,这个方法会挂起调用线程,直到被调用线程结束执行,调用线程才会继续执行
********************************* 不积跬步无以至千里,不积小流无以成江海 *********************************