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

此时,如果不使用线程,我们势必会浪费非常多的时间来完成整个大的事情,而使用线程的话将会存在这样的问题:

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

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

在这里我使用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.

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

具体情况大家可以衍生考虑,检测是否全部返回也可以有多种方式甚至设置添加一个定时器之类的。

以后有时间画一个详细点的图!

[Java][Android] 多线程同步-主线程等待所有子线程完成案例相关推荐

  1. [Java][Android] 多线程同步-主线程等待全部子线程完毕案例

    有时候我们会遇到这种问题:做一个大的事情能够被分解为做一系列相似的小的事情,而小的事情无非就是參数上有可能不同样而已! 此时,假设不使用线程,我们势必会浪费许多的时间来完毕整个大的事情.而使用线程的话 ...

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

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

  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主线程等待所有子线程执行完毕再执行解决办法(转)

    方法一: Thread.join()方法,亲测可行,thread.join()方法 [java] view plain copy Vector<Thread> ts = new Vecto ...

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

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

  9. 【Java并发编程】主线程等待子线程的多种方法

    文章目录 1.Thread sleep() 2.Thread join() 3.synchronized 等待唤醒机制 4.ExecutorService isTerminated() + while ...

  10. 主线程等待几个子线程执行完成方案

    有时,为了程序的性能,我们有必要对程序中的for循环(含有sql/rpc操作)进行并发处理,要求是并发处理完之后才能继续执行主线程.现给出如下两种方案: 1. CountDownLatch Java代 ...

最新文章

  1. Worktile 进军软件开发与协作的初心与野心
  2. socket read阻塞_go tcp中的ioutil.ReadAll阻塞的问题
  3. C 指针常量 和常量指针 指向常量的指针常量的使用
  4. VMware克隆centos系统后不能识别eth0
  5. 推荐一款优雅高效的免费在线APP原型工具
  6. UVA-1623 Enter The Dragon (贪心)
  7. 对比几段代码,看看你是 Python 菜鸟还是老鸟
  8. 【模型压缩系列】一:模型替换
  9. sci协议集群服务器,唠嗑|新出了关于SCI的规定,可我连SCI分区都没搞明白
  10. 背景的css代码,CSS 背景(示例代码)
  11. 教你编写一份高质量的软件测试报告
  12. 安装corelDraw x8过程遇到的坑
  13. 用户个人隐私保密协议
  14. Android手机“核心科技”---Vibrator(马达)驱动分析
  15. codeforces 1526C1 Potions (Easy Version)
  16. 谁来拯救中国的语言文学_习惯累积沉淀_新浪博客
  17. Java字母笔顺_j的笔顺 j书写顺序是什么
  18. 软件测试行业未来发展趋势 2020软件测试行业现状及市场前景规模分析
  19. 基于C#的全国天气查询API调用代码实例
  20. 联想WIN10进入BIOS进行设置的两种方法

热门文章

  1. android studio | openGL es 3.0增强现实(AR)开发汇总
  2. 对 n = 2,3,...,300, 判断那些 Mersenne 数 M_n=2^n-1 是素数 | matlab 源码
  3. java对象占用内存的说法_JAVA 中关于对象成员占用内存的说法哪个正确 (3.0分)_学小易找答案...
  4. Hvv近期0day总结四
  5. Chrome开发者工具对于异常请求不显示Response内容
  6. 计算机主机光驱弹不出来怎么办,win7系统电脑按下光驱按钮托盘就是弹不出来怎么办...
  7. 互相引用 spring_Spring-bean的几种循环依赖方式
  8. linux整盘远程备份,linux实现自动远程备份(scp+ssh)
  9. 【题解】保安站岗[P2458]皇宫看守[LOJ10157][SDOI2006]
  10. elementui中el-upload自定义上传方法中遇到的问题