一、join()

Thread中的join()方法就是同步,它使得线程之间由并行执行变为串行执行。

public class MyJoinTest {
public static void main(String[] args) {
Vector<Thread> threadVector = new Vector<Thread>(); for (int i = 0;i<5;i++){
Thread childThread = new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("子线程执行...");
}
});
threadVector.add(childThread);
childThread.start(); }
for (Thread t : threadVector){
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
} System.out.println("主线程执行......");
}
}

我们使用循环创建了5个子线程,把它们放到Vector对象中,并启动这个线程。遍历Vector,获取每一个子线程。在main线程中调用子线程的join方法,那么main线程放弃cpu的使用权,直到所有的子线程执行完毕,才会执行main线程。执行结果如下:

子线程执行...
子线程执行...
子线程执行...
子线程执行...
子线程执行...
主线程执行......

二、CountDownLatch

public class CountDownLatchTest {

    public static void main(String[] args) {

        final CountDownLatch latch = new CountDownLatch(5);

        for (int i = 0; i < 5; i++) {

            new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("子线程执行...");
latch.countDown();//让latch中的值减1
}
}).start(); }
try {
latch.await();//阻塞当前线程,直到latch的值为0
} catch (InterruptedException e) {
e.printStackTrace();
} System.out.println("主线程执行......"); } }

三、CyclicBarrier

public class CyclicBarrierTest {

    public static void main(String[] args) throws BrokenBarrierException, InterruptedException {

        final CyclicBarrier barrier = new CyclicBarrier(5);

        for (int i = 0; i < 4; i++) {
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
} System.out.println("子线程执行...");
try {
barrier.await();//到达屏障
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
barrier.await();
System.out.println("主线程执行......");
}
}
CountDownLatch和CyclicBarrier有什么区别呢?
他们的区别:CountDownLatch只能使用一次,而CyclicBarrier方法可以使用reset()方法重置,所以CyclicBarrier方法可以处理更为复杂的业务场景。

Java主线程在子线程执行完毕后再执行的更多相关文章

  1. Java主线程等待子线程、线程池

    public class TestThread extends Thread { public void run() { System.out.println(this.getName() + &qu ...

  2. C# 本进程执行完毕后再执行下一线程

    最近做了一套MES集成系统,由上料到成品使自动化运行,其中生产过程是逐步的,但是每一个动作都需要独立的线程进行数据监听,那么就需要实现线程等待. 代码: using System; using Sys ...

  3. java主线程捕获子线程中的异常

    本文主要参考:<think in java> 好,下面上货. 正常情况下,如果不做特殊的处理,在主线程中是不能够捕获到子线程中的异常的. 例如下面的情况. package com.xuey ...

  4. 线程:Java主线程等待子线程结束

    使用Thread.join()方法: public class App { public static void main(String[] args) { testMain(); } public ...

  5. 验证:java 主线程在子线程结束后才会结束

    package com.idealisan.test; /** * Hello world! * */ public class App { public static void main( Stri ...

  6. go实现主线程等待子线程都运行完再退出

    方式一 package main import ( "fmt" ) func main() { ch := make(chan struct{}) count := 2 // co ...

  7. java多线程实现主线程等待子线程执行完问题

    本文介绍两种主线程等待子线程的实现方式,以5个子线程来说明: 1.使用Thread的join()方法,join()方法会阻塞主线程继续向下执行. 2.使用Java.util.concurrent中的C ...

  8. JAVA进阶----主线程等待子线程各种方案比较(转)

    创建线程以及管理线程池基本理解 参考原文链接:http://www.oschina.net/question/12_11255?sort=time 一.创建一个简单的java线程 在 Java 语言中 ...

  9. Java并发编程原理与实战六:主线程等待子线程解决方案

    本文将研究的是主线程等待所有子线程执行完成之后再继续往下执行的解决方案 public class TestThread extends Thread { public void run() { Sys ...

随机推荐

  1. css的导入与基础选择器

    css是什么 css也是一门标记语言,主要用作修改控制html的样式 css书写的位置(导入) css是用来控制页面标签的样式,但是可以根据实际情况书写在不同的位置, 放在不同位置有不同的专业叫法,可 ...

  2. 映射重复导致的错误:Ambiguous handler methods mapped for HTTP path

    转自:https://cloud.tencent.com/developer/article/1372150 出现了两个名称一样的映射,会报如下错误: 原因: 解决方法: 出现Ambiguous Ma ...

  3. MySQL中SQL语句常见优化策略

    1.避免全表扫描 对查询进行优化,应尽量避免全表扫描,首先应考虑在where 及order by 涉及的列上建立索引. 2.避免判断null 值 应尽量避免在where 子句中对字段进行null 值判 ...

  4. 检测jquery是否正确引入

    if(typeof(jQuery)=="undefined"){ alert("jQuery is not imported"); }else{ alert(& ...

  5. hadoop相关随记

    1.用来查询集群上启动的job,并杀掉DumpTrack状态的job: yarn application -list|grep DumpTrack|awk '{print $1}' | xargs y ...

  6. Linux路径切换命令——directory stack

    操作directory stack一共需要3个命令: dirs .pushd.popd dirs: 显示当前目录栈 pushd: 把目录压栈 popd: 把目录弹栈 dirs 显示目录栈内容,如果没有 ...

  7. bash基础——终端

    前言 自学Linux的时候,我们用的显示器+键盘 是物理终端.Linux开机后,会在物理终端(显示器)之上,以软件的方式虚拟出多个终端,CentOS是6个.Ctrl+Alt+F1~6切换 默认情况下, ...

  8. doesn't declare an explicit app_label and isn't in an application in INSTALLED_APPS.

    在settings.py中增加 INSTALLED_APPS = [ ... 'django.contrib.sites', ] 问题就解决了.什么原因.——不知道.. 具体请看: https://s ...

  9. Redis单实例数据迁移到集群

    环境说明 单机redis redis集群 192.168.41.101:7000 master 192.168.41.101:7001 master 192.168.41.102:7000 maste ...

  10. 一、vue基础--语法

      用到的前台编程工具是Visual Studio Code,暂时是官网下载vue.js到本地使用 一.Visual Studio Code需要安装的插件: jshint :js代码规范检查 Beau ...