这里实际是考察线程间的通信,正常情况下,主线程里启动异步线程执行某个方法,理论上主线程和这个异步线程是并行执行,互不干扰,但是现在要求异步线程执行完毕方法之后,才能继续执行主线程,实际是如何阻塞主线程,到底有几种写法呢?废话少说,直接上代码!

首先先给出需要执行的方法(可以自定义):

public class Compute {public static int fibo(int a) {if ( a < 2) {return 1;}return fibo(a-1) + fibo(a-2);}}
  • 方式一:Thread.sleep()方法,让主线程休眠

代码:

public static void main(String[] args) throws InterruptedException {long start = System.currentTimeMillis();//异步执行new Thread(() -> {int result = Compute.fibo(7);System.out.println("异步线程执行结果:"+result);}).start();Thread.sleep(10000);System.out.println("main线程结束。。。");}

执行结果:

  • 方式二:用join方法阻塞主线程

代码:

public static void main(String[] args) throws InterruptedException {MyThread myThread = new MyThread();myThread.start();myThread.join();System.out.println("main线程结束。。。");}private static class MyThread extends Thread{@Overridepublic void run(){int result = Compute.fibo(7);System.out.println("异步线程执行结果:"+result);}}

执行结果:

  • 方式三:wait+synchronized阻塞主线程

代码:

public static void main(String[] args) throws InterruptedException {long start = System.currentTimeMillis();Object obj = new Object();MyThread myThread = new MyThread();myThread.start();synchronized (obj){obj.wait(1000);}System.out.println("线程:"+Thread.currentThread().getName()+" 使用时间:"+(System.currentTimeMillis()-start)+"ms");}private static class MyThread extends Thread{@Overridepublic void run(){int result = Compute.fibo(7);System.out.println("线程:"+Thread.currentThread().getName()+" 异步计算结果:"+result);}}

执行结果:

  • 方式四:wait+notify+synchronized

public static void main(String[] args) throws InterruptedException {long start = System.currentTimeMillis();Object obj = new Object();MyThread myThread = new MyThread(obj);myThread.start();synchronized (obj){obj.wait();}System.out.println("线程:"+Thread.currentThread().getName()+" 使用时间:"+(System.currentTimeMillis()-start)+"ms");}private static class MyThread extends Thread{Object obj;public MyThread(Object obj){this.obj = obj;}@Overridepublic void run(){int result = Compute.fibo(7);System.out.println("线程:"+Thread.currentThread().getName()+" 异步计算结果:"+result);synchronized (obj) {obj.notify();}}}

执行结果:

  • 方式五:ReentrantLock+Condition

private final static ReentrantLock reentrantLock = new ReentrantLock(true);private final static Condition condition = reentrantLock.newCondition();public static void main(String[] args) throws InterruptedException {long start = System.currentTimeMillis();Object obj = new Object();//异步执行new Thread(() -> {ThreadWork05.handler(obj);}).start();ThreadWork05.mainHandler(start);}private static void mainHandler(long start) throws InterruptedException {try {reentrantLock.lock();condition.await();System.out.println("线程:"+Thread.currentThread().getName()+" 使用时间:"+(System.currentTimeMillis()-start)+"ms");}finally {reentrantLock.unlock();}}private static void handler(Object obj) {try {reentrantLock.lock();int result = Compute.fibo(7);System.out.println("线程:"+Thread.currentThread().getName()+" 异步计算结果:"+result);condition.signal();}finally {reentrantLock.unlock();}}

执行结果:

  • 方式六:CountDownLatch

public static void main(String[] args) throws InterruptedException {CountDownLatch latch = new CountDownLatch(1);long start = System.currentTimeMillis();//异步执行new Thread(() -> {handler();latch.countDown();}).start();latch.await();System.out.println("线程:"+Thread.currentThread().getName()+" 使用时间:"+(System.currentTimeMillis()-start)+"ms");}private static void handler() {int result = Compute.fibo(7);System.out.println("线程:"+Thread.currentThread().getName()+" 异步计算结果:"+result);}

执行结果:

  • 方式七:LockSupport.park和unpark

public static void main(String[] args) {long start = System.currentTimeMillis();Thread mainThread = Thread.currentThread();//异步执行Thread t = new Thread(new Runnable() {@Overridepublic void run() {handler(mainThread);}});t.start();LockSupport.park(mainThread);System.out.println("线程:"+Thread.currentThread().getName()+" 使用时间:"+(System.currentTimeMillis()-start)+"ms");}private static void handler(Thread mainThread) {int result = Compute.fibo(7);System.out.println("线程:"+Thread.currentThread().getName()+" 异步计算结果:"+result);LockSupport.unpark(mainThread);}

执行结果:

  • 方式八:LockSupport.parkNanos 超时时间

    public static void main(String[] args) {long start = System.currentTimeMillis();Thread mainThread = Thread.currentThread();//异步执行Thread t = new Thread(new Runnable() {@Overridepublic void run() {handler();}});t.start();LockSupport.parkNanos(mainThread, 100L);System.out.println("线程:"+Thread.currentThread().getName()+" 使用时间:"+(System.currentTimeMillis()-start)+"ms");}private static void handler() {int result = Compute.fibo(7);System.out.println("线程:"+Thread.currentThread().getName()+" 异步计算结果:"+result);}

    执行结果:

  • 方式九:LockSupport.parkUntil 截止到某时间点释放方式

public static void main(String[] args) {long start = System.currentTimeMillis();Thread mainThread = Thread.currentThread();//异步执行Thread t = new Thread(new Runnable() {@Overridepublic void run() {handler();}});t.start();LockSupport.parkUntil(mainThread, System.currentTimeMillis()+1000);System.out.println("线程:"+Thread.currentThread().getName()+" 使用时间:"+(System.currentTimeMillis()-start)+"ms");}private static void handler() {int result = Compute.fibo(7);System.out.println("线程:"+Thread.currentThread().getName()+" 异步计算结果:"+result);}

执行结果:

  • 方式十:CountDownLatch.await(long t, TimeUtil t)

public static void main(String[] args) throws InterruptedException {CountDownLatch latch = new CountDownLatch(1);long start = System.currentTimeMillis();//异步执行new Thread(() -> {handler();}).start();latch.await(100, TimeUnit.MILLISECONDS);System.out.println("线程:"+Thread.currentThread().getName()+" 使用时间:"+(System.currentTimeMillis()-start)+"ms");}private static void handler() {int result = Compute.fibo(7);System.out.println("线程:"+Thread.currentThread().getName()+" 异步计算结果:"+result);}

执行结果:

  • 方式十一:ExecutorService.submit+Future.get()阻塞 线程池

public static void main(String[] args) {long start = System.currentTimeMillis();ExecutorService executorService = new ThreadPoolExecutor(2,2,0L,TimeUnit.MILLISECONDS,new LinkedBlockingQueue<>());Future<Integer> future = executorService.submit(new Callable<Integer>() {@Overridepublic Integer call() throws Exception {return handler();}});try {System.out.println("异步线程输出结果:"+future.get());} catch (InterruptedException e) {e.printStackTrace();} catch (ExecutionException e) {e.printStackTrace();}executorService.shutdown();System.out.println("线程:"+Thread.currentThread().getName()+" 使用时间:"+(System.currentTimeMillis()-start)+"ms");}private static int handler() {int result = Compute.fibo(7);System.out.println("线程:"+Thread.currentThread().getName()+" 异步计算结果:"+result);return result;}

执行结果:

  • 方式十二:线程池+synchronized  方式,下面要么同时锁住oo,要么同时锁住mainThread,效果一样

public static void main(String[] args) {Object oo = new Object();Thread mainThread = Thread.currentThread();long start = System.currentTimeMillis();ExecutorService executorService = new ThreadPoolExecutor(0, Integer.MAX_VALUE,60L, TimeUnit.SECONDS,new SynchronousQueue<Runnable>());executorService.execute(new Runnable() {@Overridepublic void run() {handler(oo, mainThread);}});executorService.shutdown();synchronized (mainThread){try {mainThread.wait();} catch (InterruptedException e) {e.printStackTrace();}}System.out.println("线程:"+Thread.currentThread().getName()+" 使用时间:"+(System.currentTimeMillis()-start)+"ms");}private static int handler(Object oo, Thread mainThread) {int result = Compute.fibo(7);System.out.println("线程:"+Thread.currentThread().getName()+" 异步计算结果:"+result);synchronized (mainThread){mainThread.notify();}return result;}

执行结果:

  • 方式十三:FutureTask+异步线程启动+future.get()阻塞

public static void main(String[] args) {long start = System.currentTimeMillis();FutureTask<Integer> futureTask = new FutureTask<>(new Callable<Integer>() {@Overridepublic Integer call() throws Exception {return handler();}});//异步启动new Thread(futureTask).start();try {System.out.println("异步线程输出结果:"+futureTask.get());} catch (InterruptedException e) {e.printStackTrace();} catch (ExecutionException e) {e.printStackTrace();}System.out.println("线程:"+Thread.currentThread().getName()+" 使用时间:"+(System.currentTimeMillis()-start)+"ms");}private static int handler() {int result = Compute.fibo(7);System.out.println("线程:"+Thread.currentThread().getName()+" 异步计算结果:"+result);return result;}

执行结果:

  • 方式十四:CompletableFuture.supplyAsync()  ,分为指定线程池和默认线程池两种

public static void main(String[] args) throws ExecutionException, InterruptedException {long start = System.currentTimeMillis();//如果不指定线程池默认使用ForkJoinPool.commonPool()
//        CompletableFuture<Integer> integerCompletableFuture = CompletableFuture.supplyAsync(() -> {
//            return handler();
//        });//也可以指定线程池ExecutorService executorService = new ThreadPoolExecutor(2,2,0L,TimeUnit.MILLISECONDS,new LinkedBlockingQueue<>());CompletableFuture<Integer> integerCompletableFuture = CompletableFuture.supplyAsync(() -> {return handler();}, executorService);System.out.println("异步输出结果:"+integerCompletableFuture.get());//如果指定了线程池得关闭executorService.shutdown();System.out.println("线程:"+Thread.currentThread().getName()+" 使用时间:"+(System.currentTimeMillis()-start)+"ms");}private static int handler() {int result = Compute.fibo(7);System.out.println("线程:"+Thread.currentThread().getName()+" 异步计算结果:"+result);return result;}

执行结果:

  • 方式十五:CompletableFuture.runAsync()  ,分为指定线程池和默认线程池两种

public static void main(String[] args) throws ExecutionException, InterruptedException {long start = System.currentTimeMillis();//如果不指定线程池默认使用ForkJoinPool.commonPool()CompletableFuture<Void> integerCompletableFuture = CompletableFuture.runAsync(() -> {handler();});//也可以指定线程池
//        ExecutorService executorService = new ThreadPoolExecutor(2,2,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<>());
//        CompletableFuture<Void> integerCompletableFuture = CompletableFuture.runAsync(() -> {
//            handler();
//        }, executorService);//runAsync没有返回值,输出为nullSystem.out.println("异步输出结果:"+integerCompletableFuture.get());//如果指定了线程池得关闭
//        executorService.shutdown();System.out.println("线程:"+Thread.currentThread().getName()+" 使用时间:"+(System.currentTimeMillis()-start)+"ms");}private static int handler() {int result = Compute.fibo(7);System.out.println("线程:"+Thread.currentThread().getName()+" 异步计算结果:"+result);return result;}

执行结果:

以上是十五种阻塞主线程的方式,还有其他方式吗?欢迎留言!

阻塞主线程,等待异步子线程执行完毕再退出主线程,有几种写法?相关推荐

  1. 【前端】等待异步任务js执行完毕再执行

    [前端]等待异步任务js执行完毕再执行 //页面加载完毕后执行 $(function(){console.info('---- 我是js代码 Start ----');//异步方法集合let prom ...

  2. 判断线程是否执行完毕_Java并发编程 | 线程核心机制,基础概念扩展

    源码地址:GitHub || GitEE 一.线程基本机制 1.概念描述 并发编程的特点是:可以将程序划分为多个分离且独立运行的任务,通过线程来驱动这些独立的任务执行,从而提升整体的效率.下面提供一个 ...

  3. Java 监控线程池所有任务是否执行完毕

    Java 监控线程池所有任务是否执行完毕 场景引入 在最近的工作中遇到一个需要批量生产百万数据并写入数据库的需求,先通过单线程的方式去实现,但是感觉效率一般,然后通过多线程的方式去改进,但是遇到下面的 ...

  4. python进程的注意点(进程之间不共享全局变量、主进程会等待所有的子进程执行结束再结束)

    1. 进程的注意点介绍 进程之间不共享全局变量 主进程会等待所有的子进程执行结束再结束 2. 进程之间不共享全局变量 import multiprocessing import time# 定义全局变 ...

  5. 线程其实就是一个个指令组成的,当这个线程内的指令全部执行完了,那么这个线程也就执行结束了

    线程其实就是一个个指令组成的,当这个线程内的指令全部执行完了,那么这个线程也就执行结束了

  6. Thread:主线程等待子线程执行完毕再执行解决办法

    线程从启动到执行完毕,一般会有一些耗时操作,并不能像一般的程序语句,就能立马结束.如下代码: package com.xxx.async; public class WaitThreadDone {p ...

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

    前言:在工作项目中,有很多耗时处理都需要开多线程运行.简单的接口可以直接异步处理解决,但是对于一些业务逻辑复杂需要同步返回的这时候就需要用到以下三个多线程等待方法了. 1.  thread.join( ...

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

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

  9. c语言主线程退出子线程,简单了解C语言中主线程退出对子线程的影响

    这篇文章主要介绍了简单了解C语言中主线程退出对子线程的影响,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 对于程序来说,如果主进程在子进程还未结束时 ...

最新文章

  1. 动态划分VLAN的方法中不包括(23)。【答案】C
  2. 逻辑回归原理(python代码实现)
  3. MariaDB 求和,最大值,最小值,平均数
  4. Linux系统下挂载Windows分区
  5. 推荐25个非常优秀的网页表单设计案例
  6. 聊一聊Yarp结合Nacos完成服务发现
  7. Maven高级之archetype(原型/骨架)开发
  8. Python 获取(字典)字符串时间区间并转换类型,判断该时间段属否在时间范围
  9. C# 在采集数据时的验证与登录处理
  10. torch的maximum与max以及导出onnx
  11. CSS3与页面布局学习总结(四)——页面布局大全
  12. 计算机连接不上蓝牙鼠标,蓝牙鼠标怎么连接到笔记本电脑?
  13. 每个人都应该具有创业精神 ——《穿布鞋的马云》读后感
  14. 3D打印中常见的7中材质分析
  15. 系统分析师电子版_3个月,我从待业青年变成数据分析师,月薪15000!
  16. 牛客小白月赛8 F-数列操作 (有序表)
  17. 使用conda管理python包和环境
  18. 使用MATLAB求图像的形心、外接矩形顶点坐标并标记
  19. 禅意花园-WEB设计优秀的参考网站
  20. 测试开发面试题(1)

热门文章

  1. 浅谈量子密钥分配技术
  2. Vue Router路由常用功能总结
  3. 2022“杭电杯”中国大学生算法设计超级联赛第七场
  4. 从操作系统内核解释电脑死机原理
  5. 软件测试工程师的前景!
  6. C语言 scanf输入回车或空格时停止输入
  7. Oracle限制单个用户的并发连接数
  8. ORA-04044:此处不允许过程、函数、程序包或类型,系统分析与解决
  9. MySQL+Java实现父子级联查询
  10. AAAI 2023 | 从谱的角度来看待(图)对比学习