为了保证系统响应迅速,需要寻找一种方法能够使调取接口能够异步执行,而Java正好提供了类似的方法,在java.util.concurrent中包含了Future相关的类,运用其中的一些类可以进行异步计算,以减少主线程的等待时间。比如启动一个main方法,main中又包含了若干个其它任务,在不使用Java future的情况下,main方法中的任务会同步阻塞执行,一个执行完成后,才能去执行另一个;如果使用java future,则main方法中的任务会异步执行,main方法不用等待一个任务的执行完成,只需往下执行就行。一个任务的执行结果又该怎么获取呢?这里就需要用到Future接口中的isDone()方法来判断任务是否执行完,如果执行完成则可获取结果,如果没有完成则需要等待。 **可见虽然主线程中的多个任务是异步执行,但是无法确定任务什么时候执行完成,只能通过不断去监听以获取结果,所以这里是阻塞的。这样,可能某一个任务执行时间很长会拖累整个主任务的执行。**

还是那句话,废话不多说,直接上代码:

package com.aplus.controller;

import lombok.extern.slf4j.Slf4j;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;

import java.util.Random;

import java.util.concurrent.Callable;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

import java.util.concurrent.Future;

/**

* @author whb

*/

@Slf4j

@RestController

@RequestMapping(value = "/api/guava")

public class GuavaController {

public static final ExecutorService service = Executors.newCachedThreadPool();

public static void main(String[] args) throws Exception {

long start = System.currentTimeMillis();

// 任务1

Future booleanTask = service.submit(new Callable() {

@Override

public Boolean call() throws Exception {

Thread.sleep(10000);

return true;

}

});

// 任务2

Future stringTask = service.submit(new Callable() {

@Override

public String call() throws Exception {

Thread.sleep(3000);

return "Hello World";

}

});

// 任务3

Future integerTask = service.submit(new Callable() {

@Override

public Integer call() throws Exception {

Thread.sleep(2000);

return new Random().nextInt(100);

}

});

while (true) {

if (booleanTask.isDone() && !booleanTask.isCancelled()) {

Boolean result = booleanTask.get();

System.err.println("任务1-10s: " + result);

break;

}

}

while (true) {

if (stringTask.isDone() && !stringTask.isCancelled()) {

String result = stringTask.get();

System.err.println("任务2-3s: " + result);

break;

}

}

while (true) {

if (integerTask.isDone() && !integerTask.isCancelled()) {

Integer result = integerTask.get();

System.err.println("任务3-2s:" + result);

break;

}

}

// 执行时间

System.err.println("time: " + (System.currentTimeMillis() - start));

}

}

解释一波:

启动一个线程池,有三个线程和三个任务,分别是线程1,线程2,线程3;线程1执行任务1(耗时10s),线程2执行任务2(耗时3s),线程3执行任务3(耗时2s);

Thread1 ——> Task1 10s

Thread2 ——> Task2 2s

Thread3 ——> Task3 3s

我们运行程序看效果:

![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzMzMTAxNjc1_size_16_color_FFFFFF_t_70][]

因为我们一开始用 Thread1.get() 获取第一个线程的结果时,是阻塞的,而且我们假定任务1执行了10s钟,导致了线程2(3s就执行完任务)和线程3(2s就执行完任务)都执行完了任务,也不打印出来。那在实际业务中,这种方法肯定是不可取的。

所以接下来我们引入 [Guava Future](/article/details/1011093225221856)

[watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzMzMTAxNjc1_size_16_color_FFFFFF_t_70]: /images/1602422945647.png

java判断线程阻塞_JDK.Future.get() :多线程里获取线程执行结果,异步阻塞问题相关推荐

  1. java 线程访问控件_C#多线程与跨线程访问界面控件的方法

    本文实例讲述了C#多线程与跨线程访问界面控件的方法.分享给大家供大家参考.具体分析如下: 在编写WinForm访问WebService时,常会遇到因为网络延迟造成界面卡死的现象.启用新线程去访问Web ...

  2. 线程基础知识_Synchronized_ThreadAPI_自定义锁_获取线程运行时异常

    Synchronized synchronized包含monitor enter, monitor exit 2个JVM指令(遵循happens-before原则), 执行monitor exit之前 ...

  3. 用java线程绘制图案_关于多线程:使用线程在java中绘制面板

    我正在编写一个包含许多不同视图的程序. 其中一个是相当图形密集型(它显示一个互连的图形). 其他人只是展示小而复杂的图表. 我发现主视图的绘制时间很长(甚至只绘制当前可见的区域),并且在绘制时,界面的 ...

  4. java判断按钮已选择的值_如何获取buttonGroup的选定单选按钮的值 - java

    如何获得所选radioButton的值? 我尝试使用buttonGroup1.getSelection().getActionCommand()(如此处的一些答案中所述),但是它不起作用. 另外,我暂 ...

  5. java线程池_Java多线程并发:线程基本方法+线程池原理+阻塞队列原理技术分享...

    线程基本方法有哪些? 线程相关的基本方法有 wait,notify,notifyAll,sleep,join,yield 等. 线程等待(wait) 调用该方法的线程进入 WAITING 状态,只有等 ...

  6. Java多线程学习(二)---线程创建方式

    线程创建方式 摘要: 1. 通过继承Thread类来创建并启动多线程的方式 2. 通过实现Runnable接口来创建并启动线程的方式 3. 通过实现Callable接口来创建并启动线程的方式 4. 总 ...

  7. java基础提升(二):多线程、线程安全、线程状态、等待唤醒机制、线程池

    目录 一. 多线程 1.1并发与并行 1.2 线程与进程 1.3 创建线程类 1.3.1 方式一:继承Thread类 1.3.2 方式二:实现Runnable接口 1.3.3 Thread和Runna ...

  8. java里新建线程设置线程名字_多线程开发不得不掌握,设置和获取线程名称及JVM如何运行的...

    原标题:多线程开发不得不掌握,设置和获取线程名称及JVM如何运行的 欲善编程,多看.多敲.多讨论:动眼.动手.动大脑. 1 如何设置和获取线程名称 多线程的运行状态是不确定的,在程序开发过程中,想要获 ...

  9. 23.多线程(进程的概述和多进程的意义,线程的概述和多线程的意义,JVM运行原理以及JVM启动的线程探讨,实现多线程 线程调度,线程控制,Lock锁,死锁现象)

    1.进程概述及多进程的意义 1.线程和进程     要想说线程,首先必须得聊聊进程,因为线程是依赖于进程存在的. 2.进程概述     什么是进程呢?通过任务管理器我们就可以看到进程的存在.      ...

  10. Java20-day11【实现多线程(进程、线程-调度-控制-生命周期)、线程同步(同步代码块、线程安全、Lock)、生产者消费者(模式概述、案例)】

    视频+资料[链接:https://pan.baidu.com/s/1MdFNUADVSFf-lVw3SJRvtg   提取码:zjxs] Java基础--学习笔记(零起点打开java世界的大门)--博 ...

最新文章

  1. dex-method-counts的用法
  2. 【POJ3264】Balanced Lineup,线段树入门
  3. python接口自动化登录_python 接口自动化--登录
  4. 入口文件到控制器 php,tp5.0框架隐藏index.php入口文件及模块和控制器的方法分析...
  5. 因为重置网络“netsh winsock reset”导致开不了机
  6. oppo 小米,vivo等手机获取root方法,绝对可靠
  7. MySQL字符串拼接函数使用
  8. SSD 网络基本原理记录
  9. 51单片机复习:红外通信
  10. Adjacent Bit Counts
  11. 虚拟机挂起后硬盘响应变慢,SCSI转IDE方法
  12. VSS配置及使用说明
  13. Kalilinux2017.2安装搜狗拼音输入法
  14. 蓝牙知识二【FEATURE SUPPORT】【LL_PING】【 LL_LENGTH】【Private Device Address Generatio】【profile例子EXAMPLE ATT】
  15. android开发开源宝贝
  16. 中兴手机溃败大裁员 中国裁员比例将超过20%
  17. FlexSlider js——轮播
  18. hibernate的HQL查询语句
  19. 如何在vue项目中调用微信扫一扫
  20. getTime 方法

热门文章

  1. Harmony OS — ListContainer列表
  2. mysql字符集插入中文数据乱码问题
  3. S11 day 94 RestFramework 之 APIView视图
  4. Web调取摄像头拍照
  5. Latex中参考文献排序
  6. android图片选择库selectp,浅谈android的selector背景选择器
  7. WPF中DataGrid的使用实例
  8. IS-IS快速收敛调优配置实例
  9. 七大排序的 java 实现和理解
  10. 杭电计算机17年复试真题详解