有时候我们会遇到这种问题:做一个大的事情能够被分解为做一系列相似的小的事情,而小的事情无非就是參数上有可能不同样而已!

此时,假设不使用线程,我们势必会浪费许多的时间来完毕整个大的事情。而使用线程的话将会存在这种问题:

主线程启动全部子线程并发运行后主线程就直接返回了,导致外部函数判读整个大的事情完毕了,可是实际上并没有完毕!

针对以上情况我想我会採用多线程方式运行同一时候解决主线程等待子线程的问题。如图:

在这里我使用Java进行案例分析。

首先建立一个线程管理类。用于启动全部子线程和等待全部子线程完毕。在这里不使用休眠一段时间后循环检測的方式(消耗CUP同一时候消耗时间,全部完毕时间不够及时等缺点)。而是使用等待临界值的方式。

ThreadManager.java例如以下:

public class ThreadManager implements NotifyInterface {private final Object mLock = new Object();private int mCount = 0;private int endCount = 0;public ThreadManager(int count) {System.out.println("Manager In.");this.mCount = count;this.addThread();synchronized (mLock) {while (true) {if (checkEnd())break;try {mLock.wait();} catch (InterruptedException e) {e.printStackTrace();}}}System.out.println("Manager Out.");}private void addThread() {System.out.println("Manager addThread().");for (int i = 1; i <= mCount; i++) {ThreadDoThing dThread = new ThreadDoThing(i, "T" + i, this);// StartdThread.start();}}private boolean checkEnd() {boolean bFlag = false;bFlag = endCount >= mCount;System.out.println("Manager checkEnd().Return is:" + bFlag);return bFlag;}@Overridepublic void runEnd() {synchronized (mLock) {++endCount;mLock.notifyAll();}}
}

此类集成自:NotifyInterface接口,NotifyInterface是用于子线程通知主线程自己已经完毕工作所用类。ThreadManager实例化时将传入一个int值,用于设置启动的子线程数,当然这里是为了简介所以採用的这种方式,实际情况可能更加复杂。

在实例化后  进入构造方法,此时将会启动子线程,启动后进入循环等待中,当检測到全部子线程完毕时就退出循环,没有就将进入临界值等待,直到通过接口通知主线程完毕时将会通知临界值一次。此时循环将会运行一次。假设不满足退出条件将继续等待临界值。直到满足为止。

NotifyInterface接口例如以下:

public interface NotifyInterface {public abstract void runEnd();}

測试用的子线程ThreadDoThing.java例如以下:

public class ThreadDoThing extends Thread {private NotifyInterface mInterface = null;private int mId = 0;private String mArgs = null;public ThreadDoThing(int id, String args, NotifyInterface iface) {this.mId = id;this.mArgs = args;this.AddInterface(iface);}public void AddInterface(NotifyInterface iface) {this.mInterface = iface;}@Overridepublic void run() {System.out.println("ThreadDoThing Id is:" + this.mId + " Args is:" + this.mArgs);System.out.println(this.mId + ":Doing...");int sleepTime = (int) (Math.random() * 1000);try {Thread.sleep(sleepTime);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(this.mId + ":SleepTime is:" + sleepTime);this.notifyEnd();System.out.println(this.mId + ":Do End.");}private void notifyEnd() {if (this.mInterface != null)this.mInterface.runEnd();System.out.println(this.mId + ":Notify End.");}
}

此类继承自Thread类,可直接重写Run()方法完毕所做工作。

在工作中,我使用了随机一个1s内的休眠来取代所做工作的时间。完毕后调用接口通知完毕。

測试方法例如以下:

  /*** @param args*/public static void main(String[] args) {// TODO Auto-generated method stubThreadManager manager = new ThreadManager(10);}

測试结果:

Manager In.
Manager addThread().
ThreadDoThing Id is:1 Args is:T1
ThreadDoThing Id is:2 Args is:T2
2:Doing...
1:Doing...
ThreadDoThing Id is:3 Args is:T3
ThreadDoThing Id is:4 Args is:T4
3:Doing...
4:Doing...
ThreadDoThing Id is:5 Args is:T5
5:Doing...
ThreadDoThing Id is:6 Args is:T6
Manager checkEnd().Return is:false
ThreadDoThing Id is:8 Args is:T8
ThreadDoThing Id is:7 Args is:T7
8:Doing...
ThreadDoThing Id is:9 Args is:T9
9:Doing...
6:Doing...
ThreadDoThing Id is:10 Args is:T10
7:Doing...
10:Doing...
3:SleepTime is:111
3:Notify End.
3:Do End.
Manager checkEnd().Return is:false
5:SleepTime is:142
5:Notify End.
Manager checkEnd().Return is:false
5:Do End.
4:SleepTime is:199
4:Notify End.
Manager checkEnd().Return is:false
4:Do End.
7:SleepTime is:342
7:Notify End.
Manager checkEnd().Return is:false
7:Do End.
10:SleepTime is:346
10:Notify End.
Manager checkEnd().Return is:false
10:Do End.
6:SleepTime is:397
6:Notify End.
Manager checkEnd().Return is:false
6:Do End.
9:SleepTime is:468
9:Notify End.
Manager checkEnd().Return is:false
9:Do End.
1:SleepTime is:475
1:Notify End.
Manager checkEnd().Return is:false
1:Do End.
2:SleepTime is:686
Manager checkEnd().Return is:false
2:Notify End.
2:Do End.
8:SleepTime is:828
8:Notify End.
Manager checkEnd().Return is:true
8:Do End.
Manager Out.

实际情况可能更加复杂。甚至子线程下还有很多其它的子线程!

详细情况大家能够衍生考虑,检測是否所有返回也能够有多种方式甚至设置加入一个定时器之类的。

以后有时间画一个具体点的图!

转载于:https://www.cnblogs.com/yangykaifa/p/7154749.html

[Java][Android] 多线程同步-主线程等待全部子线程完毕案例相关推荐

  1. python 主程序等待 子线程_Python多线程中主线程等待所有子线程结束的方法

    Python多线程中主线程等待所有子线程结束的方法 发布时间:2020-07-30 14:39:04 来源:亿速云 阅读:77 作者:小猪 这篇文章主要讲解了Python多线程中主线程等待所有子线程结 ...

  2. DLL内线程同步主线程研究(子线程代码放到主线程执行)

    DLL内线程同步主线程研究(子线程代码放到主线程执行) 我们在实际项目中经常会用到多线程编程,比如Socket编程等,在创建的线程内同步主线程一般使用Synchronize方法实现子线程操作放到主线程 ...

  3. Java多线程、主线程等待所有子线程执行完毕、共享资源

    1.Java创建与启动线程 Java提供两种方式创建和启动线程:1.直接Thread类,2.实现Runable接口. 1.1  继承Thread类 public class myThread exte ...

  4. java主线程等待所有子线程执行完毕再执行

    java主线程等待所有子线程执行完毕在执行,这个需求其实我们在工作中经常会用到,比如用户下单一个产品,后台会做一系列的处理,为了提高效率,每个处理都可以用一个线程来执行,所有处理完成了之后才会返回给用 ...

  5. java 父线程_Java父线程(或是主线程)等待所有子线程退出的实例

    导读热词 实例如下: static void testLock1(){ final AtomicInteger waitCount = new AtomicInteger(30000); final ...

  6. 主线程等待所有子线程结束的4种方法

    目录 主线程不等待子线程全部结束 1.使用CountDownLatch 2.同步屏障CyclicBarrier 2.1.CyclicBarrier使用 2.2.CyclicBarrier复用 2.3. ...

  7. java main 如何不退出_为什么java main主线程退出了子线程还能运行;golang main结束所有协程都被结束了...

    最近看golang main函数结束,所有协程都被结束了 结论是这样:A不是main程的情况下,在A程里开启B程,A程执行完,A程return之后,B程不受影响,不会挂掉.所有子协程与main程同级的 ...

  8. Java中主线程如何捕获子线程抛出的异常

    Java中主线程如何捕获子线程抛出的异常 参考文章: (1)Java中主线程如何捕获子线程抛出的异常 (2)https://www.cnblogs.com/jpfss/p/10272885.html ...

  9. 【Android 异步操作】Android 线程切换 ( 判定当前线程是否是主线程 | 子线程中执行主线程方法 | 主线程中执行子线程方法 )

    文章目录 一.判定当前线程是否是主线程 二.子线程中执行主线程方法 三.主线程中执行子线程方法 一.判定当前线程是否是主线程 在 Android 中 , 如果要判定当前线程是否是主线程 , 可以使用如 ...

最新文章

  1. 训练神经网络最应该注意什么才能让显卡最大限度的发挥性能
  2. python写一个通讯录V2.0
  3. “斐波那契数列”的两种算法
  4. python中值滤波去除椒盐噪声_python 中值滤波,椒盐去噪,图片增强实例
  5. 实现路由器无线接收另一个路由器无线信号搭建网络
  6. matlab创建nc文件怎么打开,MATLAB打开nc文件并读取nc文件数据
  7. 小希的迷宫(HDU 1272 并查集判断生成树)
  8. ACM_一道耗时间的水题
  9. java 没有junit包,~项目导入时报错:程序包org.junit不存在
  10. kangle虚拟主机系统easypanel使用教程
  11. Latex添加一条水平线
  12. 阿里云域名注册+网站备案
  13. windows下AV1的编译
  14. Linux 性能优化全景指南
  15. 导热系数仪 德国PSL 德国培赛乐 快速阻垢性能测试仪 抗车辙剂 摇摆槽 水合物摇摆槽 水合物相变的固-液-气多相流动 水合物阻聚剂分析 沥青硫化氢分析 沥青絮凝点 沥青絮凝点测定仪 油田注水阻垢剂
  16. <数据库概论> 如何把E-R图(概念模型)转换为关系模式(逻辑模型)
  17. base64编码图片数据存储服务器
  18. 温哥华岛大学计算机科学,温哥华岛大学有几个校区?
  19. 随机数函数rand()和srand()的区别
  20. 柳岩清晨晒素颜照称拿去辟邪 网友称吓人没认出来

热门文章

  1. 用maven创建Spring MVC项目
  2. 有关贝祖定理的一个小问题
  3. Offer是否具有法律效力?
  4. 【Android】BroadCast广播机制应用与实例
  5. Apache服务器主配置文件 httpd.conf 中文版
  6. OpenCV的HSV空间度量与标准HSV不一样,使用的时候需要换算;另附一个调色取色的小工具
  7. linux下实用小脚本,十个增加 Linux Shell 脚本趣味的小工具
  8. mysql删除表命令_MySQL创建和删除表操作命令实例讲解
  9. 用nice等命令设定的进程优先级有什么确切的含义?
  10. client-go删除job同时删除job关联的pod