关于Thread的join方法

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方法当我们调用某个线程的这个方法时,这个方法会挂起调用线程,直到被调用线程结束执行,调用线程才会继续执行

********************************* 不积跬步无以至千里,不积小流无以成江海 *********************************

猜你喜欢

转载自blog.csdn.net/weixin_42465125/article/details/89348943