一个线程启动之后, 是异步的去执行需要执行的内容的, 不会影响主线程的流程,  往往需要让主线程指定后, 等待子线程的完成. 这里有几种方式。

站在主线程的角度, 我们可以分为 主动式 被动式 .

主动式指主线程主动去检测某个标志位, 判断子线程是否已经完成. 被动式指主线程被动的等待子线程的结束, 很明显, 比较符合人们的胃口. 就是你事情做完了, 你告诉我, 我汇总一下, 哈哈.

1.      JoinDemo(主动式)

目的:等待当前线程的die

package com.test;
public class JoinDemo {
    public static void main(String[] args) throws Exception {
        //创建子线程,并启动子线程
        Thread subThread = new Thread(new SubThread());
        subThread.start();
        //主线程处理其他工作,让子线程异步去执行
        mainWork();
        //主线程其他工作完毕,等待子线程的结束, 调用join系列的方法即可(可以设置超时时间)
        subThread.join();
        System.out.println("Now all thread done!");
    private static void mainWork() throws Exception{
        System.out.println("Main thread start work!");
        //sleep
        Thread.sleep(2000L);
        System.out.println("Main Thread work done!");
     * 子线程类
     * @author fuhg
    private static class SubThread implements Runnable{
        public void run() {
            // TODO Auto-generated method stub
            System.out.println("Sub thread is starting!");
            try {
                Thread.sleep(5000L);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            System.out.println("Sub thread is stopping!");

2.      FutureDemo

  使用并发包下面的Future模式.

  Future是一个任务执行的结果, 他是一个将来时, 即一个任务执行, 立即异步返回一个Future对象, 等到任务结束的时候, 会把值返回给这个future对象里面. 我们可以使用    ExecutorService接口来提交一个线程.(注意:Future.get()为一个阻塞方法)

package com.test;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class FutureDemo {
    //创建一个容量为1的线程池
    static ExecutorService executorService = Executors.newFixedThreadPool(1);
    public static void main(String[] args) throws Exception {
        //创建线程并提交线程,同时获取一个future对象
        Thread subThread = new Thread(new SubThread());
        Future future = executorService.submit(subThread);
        //主线程处理其他工作,让子线程异步去执行
        mainWork();
        //阻塞,等待子线程结束
        future.get();
        System.out.println("Now all thread done!");
        //关闭线程池
        executorService.shutdown();
    //主线程工作
    private static void mainWork(){
        System.out.println("Main thread start work!");
        try {
            Thread.sleep(2000L);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        System.out.println("Main Thread work done!");
     * 子线程类
     * @author fuhg
    private static class SubThread implements Runnable{
        public void run() {
            // TODO Auto-generated method stub
            System.out.println("Sub thread is starting!");
            try {
                Thread.sleep(5000L);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            System.out.println("Sub thread is stopping!");

3.      CountDownDemo

  上面两种情况在线程数为一两个的时候,还可以,如果需要控制的线程数很多的话,再采取这种方式就有点过意不去了。

  第一种方法, 你要调用很多个线程的join, 特别是当你的线程不是for循环创建的, 而是一个一个创建的时候.

  第二种方法, 要调用很多的future的get方法, 同第一种方法.

  所以去Concurrent库里面找找看还有什么东东吧。

  CountDownLanch 是一个倒数计数器, 给一个初始值(>=0), 然后每一次调用countDown就会减1, 这很符合等待多个子线程结束的场景: 一个线程结束的时候, countDown一次, 直到所有的线程都countDown了 , 那么所有子线程就都结束了.

  先看看CountDownLanch提供的方法吧

await: 会阻塞等待计数器减少到0位置. 带参数的await是多了等待时间.

countDown: 将当前的计数减1

getCount(): 返回当前的计数

显而易见, 我们只需要在子线程执行之前, 赋予初始化countDownLanch, 并赋予线程数量为初始值.

每个线程执行完毕的时候, 就countDown一下.主线程只需要调用await方法, 可以等待所有子线程执行结束。

package com.test;
import java.util.concurrent.CountDownLatch;
public class CountDownDemo {
    public static void main(String[] args) throws Exception {
        //定义线程数
        int subThreadNum = 5;
        //取得一个倒计时器,从5开始
        CountDownLatch countDownLatch = new CountDownLatch(subThreadNum);
        //依次创建5个线程,并启动
        for (int i = 0; i < subThreadNum; i++) {
            new SubThread(2000*(i+1), countDownLatch).start();
        //主线程工作
        mainWork();
        //等待所有的子线程结束
        countDownLatch.await();
        System.out.println("Main Thread work done!");
    private static void mainWork(){
        System.out.println("Main thread start work!");
        try {
            Thread.sleep(2000L);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        System.out.println("Main Thread work done!");
     * 子线程类
     * @author fuhg
    private static class SubThread extends Thread{
        private CountDownLatch countDownLatch;
        private long workTime;
        public SubThread(long workTime,CountDownLatch countDownLatch){
            this.workTime = workTime;
            this.countDownLatch = countDownLatch;
        public void run() {
            // TODO Auto-generated method stub
            try {
                System.out.println("Sub thread is starting!");
                Thread.sleep(workTime);
                System.out.println("Sub thread is stopping!");
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } finally {
                //线程结束时,将计时器减一
                countDownLatch.countDown();

转载:https://www.cnblogs.com/jsunday/p/3782874.html

一个线程启动之后, 是异步的去执行需要执行的内容的, 不会影响主线程的流程, 往往需要让主线程指定后, 等待子线程的完成. 这里有几种方式。站在主线程的角度, 我们可以分为主动式和被动式.主动式指主线程主动去检测某个标志位, 判断子线程是否已经完成. 被动式指主线程被动的等待子线程的结束, 很明显, 比较符合人们的胃口. 就是你事情做完了, 你告诉我, 我汇总一下, 哈哈.1. JoinDemo(主动式)目的:等待当前线程的die示例:package com.test;...
最近遇到一个问题需要线程等待所有的线程结束,才能开始执行,统计所有的线程执行结果,返回,网上翻阅各种资料,最后记录一下,找到七种方案 第一种:while循环 对于“等待所有的线程结束”的问题,最开始想到的是使用while循环进行轮询: //开始计时 String start = getTheTimeInMilliseconds(); System.out.println("start = " + start); Thread t = n
程序:是为完成特定任务,用某种语言编写的一组指令的集合,即指一段静态的代码,静态对象。 进程:是程序的一次执行过程,或是正在运行的一个程序,是一个动态的过程,有它自身的产生,存在和消亡的过程。-------生命周期 线程:进程可进一步细化为线程,是一个程序内部的一条执行路径 同步和异步&并发和并行 同步:排队执行,效率低但是安全 异步:同时执行,效
工作总往往会遇到异步去执行某段逻辑, 然后先处理其他事情, 处理完后再把那段逻辑的处理结果进行汇总的场景, 这时候就需要使用线程了. 一个线程启动之后, 是异步的去执行需要执行的内容的, 不会影响线程的流程, 往往需要让线程指定后, 等待线程的完成。并且,线程是要利用到线程的返回数据进行处理。这里有2种方式:实现 Callable 接口、join() 方法 1、实现 Callable 接口 class SubThread implements Callable<Integer> {
线程中join(强制执行):当前线程执行完毕之后,才会执行后面程序,其他线程阻塞; public class ThreadJoin implements Runnable{ @Override public void run() { for (int i = 1; i < 1000; i++) { System.out.println("Join..."+i+"运行中"); public stat
为了让程序尽快响应用户操作,在开发应用程序时经常会使用到线程。对于耗时操作如果不使用线程,UI界面将会长时间处于停滞状态,这种情况是用户非常不愿意看到的,我们可以用线程来解决这个问题。 前面,已经介绍了QThread常用的两种方式: Worker-Object 类化QThread 下面,我们来看看类化QThread在日常中的应用。 类化QThread 线程休眠...
在程序设计中,为了不影响程序的执行,常常把耗时操作放到一个单独的线程执行。Qt对多线程操作有着完整的支持,Qt中通过继承QThread并重写run()方法的方式实现线程代码的编写。针对线程之间的同步与互斥问题,Qt还提供了QMutex、QReadWriteLock、QwaitCondition、QSemaphore等多个类来实现。 本篇博客将针对以下几个方面进行讲解 [1]QThread...
一个QThread对象管理程序内的一个线程,QThreads在run()中开始执行。默认情况下,run()通过调用exec()启动事件循环,并在线程内部运行一个Qt事件循环。 可以通过使用 QObject::moveToThread() 将对象移动到线程来使用它们。 class Worker : public QObject Q_OBJECT public slots: void doWork(const QString &parameter) 使用Thread的join()等待所有的线程执行完毕线程执行等待线程完成的CountDownLatch; 同步屏障CyclicBarrier; 一、使用Thread的join() ​ 使用Thread的join()等待所有的线程执行完毕线程执行,thread.join()把指定的线程加入到当前线程,可以将两个交替执行线程合并为顺序执行线程。比如在线程B中调用了线程A的Join()方法,直到线程A执行完毕后,才会继
今天看到深入理解JVM第367页多线程volatile部分照着书本敲着代码发现了一个问题 Thread.activeCount()会一直大于2 public class VolatileTest { public static volatile int race = 0; public static void increase() { race++; private stati...
public class MyThread extends Thread { public void run() { // some code that might throw an exception 在线程启动等待线程完成,可以这样做: try { MyThread myThread = new MyThread(); myThread.start(); myThread.join(); // wait for the thread to finish } catch (InterruptedException e) { // handle interrupt exception } catch (Exception e) { // handle any other exception thrown by the thread 在这个例中,如果线程中抛出了一个异常,它会被线程捕获并处理。注意,线程抛出的异常必须是Throwable的类,否则它不会被捕获。同时需要注意的是,捕获线程异常的方式还有其他的实现方式,具体实现要根据实际情况而定。 水平则静: 请教一下,你使用loadImageCmd.exec这个方法,有没有出现DEBUG com.github.dockerjava.httpclient5.ApacheDockerHttpClientImpl$ApacheResponse - Failed to close the response java.net.SocketException: socket closed 我使用了docker-java和docker-java-transport-httpclient5 都3.3.0,其他版本3.2.13 12我都试过了,都是这个bug 利用Docker-java加载并将docker镜像包推送至镜像仓库 水平则静: 这个现在好像出了一个loadImageAsyncCmd的异步加载方法,里面有一些回调 spring boot 服务间传输Docker镜像,并加载镜像 水平则静: 我好奇这个loadImageCmd之后,本地docker到底有没有 image:tag ApplicationEventPublisher的使用学习 喂喂喂。。。秋雅在吗?秋雅在吗?: 抄袭了这篇文章。抄都抄错了。 https://www.jianshu.com/p/125815d5dd7c