Java多线程之----主线程会等待子线程结束再结束么,怎么让主线程等待子线程结束呐?
首先给出结论:
主线程和子线程之间没有谁先谁后结束这种关联,它们只是各自负责自己的线程任务,如果该线程的任务结束了,该线程自然会结束运行。
talk is cheap,show me the code and the result
1.先来一个好理解的:
下面这个例子中,由于子线程循环了100次,干的活多,走的慢,所以结束的晚。可以看到执行结果,主线程结束后,子线程稍等了一会才结束执行,并没有主线程需要等待子线程结束的情况。
主线程的任务:
1.thread.start 开启子线程
2.System.out.println(Thread.currentThread().getName()+“结束了 ,这是main干的活”); 输出语句
子线程的任务:
for (int i = 0; i < 100; i++) {if (i==99){System.out.println("我现在是99,这是子线程干的活");}} //循环100次,并输出语句
也就是说,谁先完成任务,谁就会先运行结束。
public class ThreadOne {public static void main(String[] args) {Thread thread = new Thread(new Runnable() {@Overridepublic void run() {for (int i = 0; i < 100; i++) {if (i==99){System.out.println("我现在是99,这是子线程干的活");}}}});thread.start();System.out.println(Thread.currentThread().getName()+"结束了 ,这是main干的活");}
}
输出结果:
main结束了 ,这是main干的活
我现在是99,这是子线程干的活
2.主线程通过方法调用开启子线程并执行任务
记得刚开始学这个的时候我也是迷惑的,为什么,主线程的方法,方法里的内容还没执行完,主线程就结束了呐,我是脸脸懵逼呀,其实,还是按照第一步中说的,看执行的任务,先上代码:
public class Outter {public static void main(String[] args) throws InterruptedException {Outter outter = new Outter();int b = 10;int test = outter.test(b);//这里调用了方法并且在方法中开启了子线程,test()方法还没执行结束,为啥主线程就走完了呐System.out.println(test);System.out.println("main 结束了");}public int test(final int b) {final int a = 10;new Thread(){public void run() {System.out.println(a);System.out.println(b);};}.start();return 5555;}
}
多次运行后,执行结果如下:
那上面这个例子中,main线程的任务是什么,子线程的任务是什么:
主线程:
1.第一部分活(干活的意思)
Outter outter = new Outter();int b = 10;int test = outter.test(b); //调用test方法System.out.println(test);System.out.println("main 结束了");
2.第二部分活
.start()开启子线程
final int a = 10;
return 5555;
子线程:
System.out.println(a);System.out.println(b);
之前一直迷惑的是,主线程调用了test()方法,为啥这个方法没结束main线程就结束了呐,其实是因为主线程只需要调用了这个方法,并且返回一个返回值,主线程的任务就结束了,至于主线程创建的子线程,去干别的事情还需要多少时间,主线程是不关心的。
举个通俗的例子:周末我在家中玩lol,正玩着突然饿了(我是主线程),喊我女朋友去搞点吃的(调用吃东西方法,吃东西方法内部,开启女朋友线程[子线程]),我接着打lol,发现打完了,女朋友还没做好饭哈哈(手动god head),我去倒头睡了。我只是调用了吃东西方法,喊一下(调用后就结束了),女朋友啥时候做好饭我不管。。。
3.可以控制让子线程结束后,主线程再结束吗。。。
上面举得例子太不真实啦哈哈,我都飘了,不过也是为了帮助理解。实际情况中,主线程可能要等待子线程执行完,返回对应的结果,取道结果后,接下来主线程继续执行或者结束。打完游戏后,我需要等女朋友把饭拿过来吃了后,我才能饱饱得睡觉哈,饭不过来,我不能睡觉,也就是子线程结束前主线程不能结束。
那有没有什么方法呐?肯定是有的哈,Java的Thread类提供了join方法。
如果需要主线程等待子线程结束,只需要在主线程的任务中,用子线程对象调用join()方法即可。
这里就不再赘述了,引用别人写的一篇文件哈,比较全面的几种方式:
引用文章原文链接:主线程等待子线程执行完毕再执行解决办法
线程从启动到执行完毕,一般会有一些耗时操作,并不能像一般的程序语句,就能立马结束。如下代码:
package com.xxx.async;public class WaitThreadDone { public static void main(String[] args) { Thread t1 = new Thread(new Runnable() { @Override public void run() { try { System.out.println("thread "+Thread.currentThread().getName()+" start to run."); Thread.sleep(2000); System.out.println("thread " + Thread.currentThread().getName() + " done."); } catch (Exception e) { e.printStackTrace(); } } }); System.out.println("main start to run."); t1.start(); System.out.println("main done."); }}
这是一个典型的线程耗时操作,默认情况下,线程t1它不会立马结束,因此执行结果就是:
我们希望主线程开始之后,等待子线程运行结束,主线程继续执行。
考虑子线程是一个耗时的阻塞操作,我们需要通过程序让子线程运行结束再执行主线程。这里给出如下几种解决办法:
①、t1.join()
②、while(t1.isAlive())
③、while(Thread.activeCount()>1)
④、CountDownLatch
下面来看看具体的实现:
第一种办法:t1.start();后面接上t1.join()代码,如下:
第二种办法:判断子线程是否还存活
第三种办法:判断活跃的线程是否大于1
第四种办法:通过同步工具类CountDownLatch实现
这种办法需要CountDownLatch对象侵入线程run()方法的代码中。最终执行结果和前面几种解决办法一致。
CountDownLatch通过await()方法阻塞主线程,等待其他线程运行结束,通过countDown()方法来释放锁,主线程开始执行。
总结:在这四种解决办法中,一、二两种办法需要知道线程的名字,当有很多线程同时执行的时候,有时候,我们是无法直观的知道每个线程的名字,这两个办法用的很少见。第四种办法在多线程的情况下也可以使用,就是需要设置CountDownLatch latch = new CountDownLatch(n),指定需要等待的线程数。第三种办法无需知道线程的名字和线程的数量,使用起来很直观。
Java多线程之----主线程会等待子线程结束再结束么,怎么让主线程等待子线程结束呐?相关推荐
- JAVA多线程执行,等待返回结果,再执行
JAVA多线程执行,等待返回结果,再执行 1.实现callable接口 1)配置线程池 package com.neusoft.demo.server.config;import org.spring ...
- Java多线程(超详解)
目录 1. 线程简介 1.1 程序 1.2 进程 1.3 线程 1.4 多线程 1.5 普通方法调用和多线程 2. 线程创建 2.1 继承Thread类 2.2 实现Runnable接口 2.3 实现 ...
- Java多线程超详解
引言 随着计算机的配置越来越高,我们需要将进程进一步优化,细分为线程,充分提高图形化界面的多线程的开发.这就要求对线程的掌握很彻底. 那么话不多说,今天本帅将记录自己线程的学习. 程序,进程,线程的基 ...
- Java 多线程深入浅出
首先关于Volatile修饰符: Volatile修饰的成员变量在每次被线程访问时,都强迫从共享内存中重读该成员变量的值.而且,当成员变量发生变化时,强迫线程将变化值回写到共享内存.这样在任何时刻,两 ...
- Java多线程的同步机制(synchronized)
一段synchronized的代码被一个线程执行之前,他要先拿到执行这段代码的权限,在 java里边就是拿到某个同步对象的锁(一个对象只有一把锁): 如果这个时候同步对象的锁被其他线程拿走了,他(这个 ...
- java word转html 烟火,Java多线程制作烟花效果.doc
Java多线程制作烟花效果 Java多线程应用实例: 制作烟花效果 本例知识点一句话讲解新学知识使用Thread类管理线程已学知识Math类产生随机数使用Color类设置颜色使用Graphics类绘制 ...
- Java多线程同步机制
一段synchronized的代码被一个线程执行之前,他要先拿到执行这段代码的权限,在 java里边就是拿到某个同步对象的锁(一个对象只有一把锁): 如果这个时候同步对象的锁被其他线程拿走了,他(这个 ...
- 【Java系列】(四)Java多线程---线程安全
前言: 记得大一刚学Java的时候,老师带着我们做了一个局域网聊天室,用到了AWT.Socket.多线程.I/O,编写的客户端和服务器,当时做出来很兴奋,回学校给同学们演示,感觉自己好NB,呵呵,扯远 ...
- Java多线程技术~生产者和消费者问题
Java多线程技术~生产者和消费者问题 本文是上一篇文章的后续,详情点击该连接 线程通信 应用场景:生产者和消费者问题 假设仓库中只能存放一件产品,生产者将生产出来的产品放入仓库,消费者将仓库中产品取 ...
最新文章
- PyTorch Multi-GPU使用代码
- linux minicom usb串口
- 初学 Delphi 嵌入汇编[1] - 汇编语言与机器语言
- Django之路--第一篇
- 在cmd中使用python使用pip报错invalid syntax
- span 标记 width 设置
- 关于SDL SDL_CreateWindowFrom和SDL_DestroyWindow第二次后无法将视频显示出来。
- 从常识看中国经济社会-再续之续:套利
- 太吾绘卷第一世攻略_建平中学高二数学周练卷(2020.09)
- 自考本科计算机类专业查询,自考本科学位如何查询
- 触动精灵mysql用法_[触动精灵]触动精灵官方手册流水账2
- 如何使得OCX控件能响应PreTranslateMessage消息?
- mac java jni_Mac OS上编译JNI的动态库
- 基于MATLAB 关于圆的研究
- Leetcode452. 用最少数量的箭引爆气球(排序+贪心)
- linux 9 -- 交互式使用Bash Shell
- java p12证书,如何使用已安装的.p12 证书在 Mac OS X 上签名 jar?
- 烽火吉比特HG261GU获取超级密码教程
- Intel编译器安装WRF-CMAQ
- android渠道首发规则,酷传推广手册Android渠道首发规则.doc