转:

Java线程池(Callable+Future模式)

Java线程池(Callable+Future模式)
Java通过Executors提供四种线程池
1)newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
2)newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
3)newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。
4)newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
在多线程的开发中往往会遇到这种情况:主线程需要知道子线程的运行结果,以便确定如何执行任务.JDK1.5以后就提供了Callable和Future,通过它们可以在任务执行完毕之后得到任务执行结果。
步骤:
1)任务类实现Callable接口
2)创建线程池:ExecutorService es = Executors.newCachedThreadPool();
3)执行任务:chuju cj = new chuju();Future<Boolean> future = es.submit(cj);
4)获取子线程中任务的执行结果:future.get()
下面通过实例简单说下其用法:
场景:假如你想做饭,但是没有厨具,也没有食材。网上购买厨具比较方便,食材去超市买更放心,即买出具、买食材,这两个任务异步执行,买好后才能去做饭。
1)chuju
public class chuju implements Callable<Boolean>{
@Override
public Boolean call() throws Exception {
try{
System.out.println("买厨具");
Thread.sleep(3000);
System.out.println("买好厨具");
}catch (InterruptedException e){
e.printStackTrace();
}
return true;
}
}
2)shicai
public class shicai implements Callable<Boolean>{
@Override
public Boolean call() throws Exception {
try{
System.out.println("买食材");
Thread.sleep(1000);
System.out.println("买好食材");
}catch(InterruptedException e){
e.printStackTrace();
}
return true;
}
}
3)zuofan
public class zuofan implements Callable<Boolean>{
@Override
public Boolean call() throws Exception {
try{
System.out.println("做饭");
Thread.sleep(5000);
System.out.println("做好饭");
}catch (InterruptedException e){
e.printStackTrace();
}
return true;
}
}
4)Main
public class Main {
public static void main(String[] args) {
ExecutorService es = Executors.newCachedThreadPool();
chuju cj = new chuju();
shicai sc = new shicai();
Future<Boolean> f1 = es.submit(cj);
Future<Boolean> f2 = es.submit(sc);
try{
Boolean b1 = f1.get();//会阻塞当前线程
Boolean b2 = f2.get();
System.out.println(b1);
System.out.println(b2);
if(b1 && b2){
zuofan zf = new zuofan();
es.submit(zf);
}
}catch(InterruptedException e){
e.printStackTrace();
}catch (ExecutionException e){
e.printStackTrace();
}
es.shutdown();
}
}
5)执行结果
Connected to the target VM, address: '127.0.0.1:57304', transport: 'socket'
买厨具
买食材
买好食材
买好厨具
true
true
做饭
Disconnected from the target VM, address: '127.0.0.1:57304', transport: 'socket'
做好饭
Process finished with exit code 0
从运行结果可以看出,买出具代码和买食材代码是异步执行的,这两个都执行完毕后,才执行的做饭代码。那么为什么子线程zuofan没有先执行呢?由于Future的get()方法没有得到返回值,让当前线程暂时挂起了。
注意:Future的get()方法,如果拿不到结果会阻塞当前线程。

Java线程池(Callable+Future模式)的更多相关文章

  1. 【Java线程】Callable和Future

    Future模式 Future接口是Java线程Future模式的实现,可以来进行异步计算. Future模式可以这样来描述: 我有一个任务,提交给了Future,Future替我完成这个任务.期间我 ...

  2. JAVA 线程池之Callable返回结果

    本文介绍如何向线程池提交任务,并获得任务的执行结果.然后模拟 线程池中的线程在执行任务的过程中抛出异常时,该如何处理. 一,执行具体任务的线程类 要想 获得 线程的执行结果,需实现Callable接口 ...

  3. Java多线程编程中Future模式的详解

    Java多线程编程中,常用的多线程设计模式包括:Future模式.Master-Worker模式.Guarded Suspeionsion模式.不变模式和生产者-消费者模式等.这篇文章主要讲述Futu ...

  4. Java多线程编程中Future模式的详解<转>

    Java多线程编程中,常用的多线程设计模式包括:Future模式.Master-Worker模式.Guarded Suspeionsion模式.不变模式和生产者-消费者模式等.这篇文章主要讲述Futu ...

  5. Netty核心概念(7)之Java线程池

    1.前言 本章本来要讲解Netty的线程模型的,但是由于其是基于Java线程池设计而封装的,所以我们先详细学习一下Java中的线程池的设计.之前也说过Netty5被放弃的原因之一就是forkjoin结 ...

  6. 深入理解Java线程池:ScheduledThreadPoolExecutor

    介绍 自JDK1.5开始,JDK提供了ScheduledThreadPoolExecutor类来支持周期性任务的调度.在这之前的实现需要依靠Timer和TimerTask或者其它第三方工具来完成.但T ...

  7. Java线程池详解(二)

    一.前言 在总结了线程池的一些原理及实现细节之后,产出了一篇文章:Java线程池详解(一),后面的(一)是在本文出现之后加上的,而本文就成了(二).因为在写完第一篇关于java线程池的文章之后,越发觉 ...

  8. Java线程池使用和源码分析

    1.为什么使用线程池 在多线程编程中一项很重要的功能就是执行任务,而执行任务的方式有很多种,为什么一定需要使用线程池呢?下面我们使用Socket编程处理请求的功能,分别对每种执行任务的方式进行分析. ...

  9. 【转载】深度解读 java 线程池设计思想及源码实现

    总览 开篇来一些废话.下图是 java 线程池几个相关类的继承结构: 先简单说说这个继承结构,Executor 位于最顶层,也是最简单的,就一个 execute(Runnable runnable) ...

随机推荐

  1. python函数大全

    1.range函数 可创建一个整数列表,用于for循环中 格式为:range(start,stop[,step]) start:计数从start开始,默认从0开始 stop:计数从stop结束,但不包 ...

  2. PAT乙级1042

    题目链接 https://pintia.cn/problem-sets/994805260223102976/problems/994805280817135616 题解 用数组count存储字母出现 ...

  3. javascript弹出带文字信息的提示框效果

    // position of the tooltip relative to the mouse in pixel // <html><head><meta charse ...

  4. HashMap源码分析二

    jdk1.2中HashMap的源码和jdk1.3中HashMap的源码基本上没变.在上篇中,我纠结的那个11和101的问题,在这边中找到答案了.   jdk1.2   public HashMap() ...

  5. JAVA遇见HTML——JSP篇(案例项目)

  6. Spring入门篇——第2章 Spring IOC容器

    第2章 Spring IOC容器 介绍Spring IOC容器的基本概念和应用 2-1 IOC及Bean容器 自己的理解:什么是IOC?就是利用配置文件(外部容器)来创建对象. 在IOC容器中,所有对 ...

  7. 打开myeclipse提示An internal error occurred during: "CheckLicensesAndNotify". com/genuitec/pulse2/client/targetcfg/ui/PulseActivator

    打开myeclipse提示An internal error occurred during: "CheckLicensesAndNotify". com/genuitec/pul ...

  8. FFmpeg常用命令学习笔记(四)处理原始数据命令

    处理原始数据命令  通过音视频设备采集的.没有经过任何加工的数据叫原始数据,而像我们平时播放的比如mp4文件是压缩后的数据.视频原始数据是YUV格式,音频原始数据是PCM格式.FFmpeg可以从封装格 ...

  9. 域知识深入学习二:建立AD DS域

    2.1 建立AD DS域前的准备工作 先安装一台服务器,然后将其升级(promote)为域控 2.1.1 选择适当的DNS域名 AD DS域名采用DNS的架构与命名方式 2.1.2 准备好一台支持AD ...

  10. P5357 【模板】AC自动机(二次加强版)

    思路 这题可以同时作为AC自动机和SAM的模板啊喂 AC自动机 对T建出AC自动机,把S在上面匹配,然后记录每个点被经过的次数,最后统计一次即可(暴力跳fail的复杂度是不对的) SAM 对S建出SA ...