小弟 今天突发奇想,想着 把并行的线程 弄成串行的。。不关用什么方法吧。反正实现了。但用到了 一个不常用的方法join。左思右想 ,终于还是觉得有必要做一次记录。
首先 看下api:
大致理解为,当前线程运行到这个方法时,会被挂起。而只有调用join方法的线程运行完毕 当前线程才继续运行。
一个简单的例子:
package com.thread; import java.util.concurrent.atomic.AtomicInteger; /** * @Description: * @Date: create in 2018-07-11 15:54 * @Author:Reynold-白 */ public class ThreadTestJoin implements Runnable { private static AtomicInteger a; public ThreadTestJoin(){ a = new AtomicInteger(0); } @Override public void run() { for(int i = 0; i < 5; i++){ System.out.println("当前线程:" + Thread.currentThread().getName() + "a 的自增结果:" + a.get()); a.getAndIncrement(); } } /** * 当 t1调用join时,主线程暂停,t1继续运行直到die 后main才继续从join方法后执行。 * 但再有个T2呢? * * * * @param args * @throws Exception */ public static void main(String[] args) throws Exception { Thread t1 = new Thread(new ThreadTestJoin()); // Thread t2 = new Thread(new ThreadTestJoin()); t1.start(); t1.join(); //等待线程 t1 终止 main才继续 t2并未执行,这样就是顺序的了 // t2.start(); // t2.join(); System.out.println(); System.out.printf("主方法中输出 a : %d\n", a.get()); } }
简单解释就是主线程执行到t1.join时,被挂起。知道t1运行完毕才执行下面的代码。
运行结果:
当我把代码中的注释放开时运行结果是:
解释:
因为当主线程运行到t1.join时,t2还没有启动(还没start呢!!),主线程就被挂起了。所以会有t1执行完再执行t2的这种结果,等t1执行完毕,主线程恢复,往下运行, 这是t2才开始运行。
但如果再换种写法呢:
运行结果:
结果显示。。我的代码中 那个a的值 初始化有些问题。。。。后期修改。尴尬。继续看join
主线程在运行t1.join前已经将两个线程启动了(不一定那个线程获取cpu资源多,有可能t2获得资源多,先执行完毕就跟图里一样,也有可能是t1先执行完毕,剩下的都是t2的信息,也有可能是交替的情况)。到了t1.join时,主线程被挂起,t2也会被挂起(如果t2还没有执行完毕)。
那要怎么实现串行呢,实现串行最直观的方案是什么呢?
其实 在run中在new 一个线程 再来一个类似递归的方法就可以了,这样就能形成一个模型:
主线程调用T1 T1 调用T2 T2.join T1会被挂起 T1.join main会被挂起。这样就是一个串行了。