concurrent包中Executor接口的主要类的关系图如下:

Executor接口非常单一,就是执行一个Runnable的命令。

public interface Executor {
void execute(Runnable command);
}

ExecutorService接口扩展了Executor接口,增加状态控制,执行多个任务返回Future。

关于状态控制的方法:

// 发出关闭信号,不会等到现有任务执行完成再返回,但是现有任务还是会继续执行,
// 可以调用awaitTermination等待所有任务执行。不再接受新的任务。
void shutdown(); // 立刻关闭,尝试取消正在执行的任务(不保证会取消成功),返回未被执行的任务
List<Runnable> shutdownNow(); // 是否发出关闭信号
boolean isShutdown(); // 是否所有任务都执行完毕在shutdown之后,也就是如果不调用shutdownNow或者
// shutdown是不可能返回true
boolean isTerminated(); // 进行等待直到所有任务完成或者超时
boolean awaitTermination(long timeout, TimeUnit unit)
throws InterruptedException;

提交单个任务,立刻返回一个Future存储任务执行的实时状态

<T> Future<T> submit(Callable<T> task);

<T> Future<T> submit(Runnable task, T result);

Future<?> submit(Runnable task);

执行多个任务的方法,有两种方式,一种等到所有任务执行完成才返回:

<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
throws InterruptedException; <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,
long timeout, TimeUnit unit)
throws InterruptedException;

另外一种是等到有一个任务完成,取消其他未完成的任务,返回执行完成的任务的执行结果:

<T> T invokeAny(Collection<? extends Callable<T>> tasks)
throws InterruptedException, ExecutionException; <T> T invokeAny(Collection<? extends Callable<T>> tasks,
long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException;

通过上面的代码可以看出ExecutorService可以执行两种类型的任务:Runnable和Callable,而Callable用的更加多。两者区别很简单,前者不会返回执行结果而后者会返回一个执行结果:

public interface Callable<V> {
V call() throws Exception;
}

接着说说Future,也就是执行任务的返回类型。Future可以看成是一张发票。比如你送件衣服到洗衣店清洗,他们会开张发票给你,你拿着发票可以去拿回你洗好的衣服或者去洗衣店问衣服是否洗好了等等。

public interface Future<V> {

    //取消任务,参数mayInterruptIfRunning为true时,如果要取消的任务正在执行,
//会把执行这个任务的线程设为中断,为false时,正在执行的任务会被允许执行完成
boolean cancel(boolean mayInterruptIfRunning); boolean isCancelled(); boolean isDone(); //获取执行结果,如果任务执行中,会等到任务完成再返回
V get() throws InterruptedException, ExecutionException; V get(long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException;
}

最后看看ScheduledExecutorService接口,该接口是ExecutorService的子接口,增加了定时执行任务的功能:

public interface ScheduledExecutorService extends ExecutorService {

    public ScheduledFuture<?> schedule(Runnable command,
long delay, TimeUnit unit); public <V> ScheduledFuture<V> schedule(Callable<V> callable,
long delay, TimeUnit unit);
// 等待一定时间然后开始执行一个任务,每隔period参数设置的时间
// 重复一次,(多线程执行)
public ScheduledFuture<?> scheduleAtFixedRate(Runnable command,
long initialDelay,
long period,
TimeUnit unit); // 等待一定时间然后开始执行一个任务,完成后,等待delay参数设置的时间
// 然后在执行一次任务。(单线程执行)
public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command,
long initialDelay,
long delay,
TimeUnit unit); }

这篇文章主要就讲到了concurrent包关于线程池的相关接口,接下来会讲AbstractExecutorService,ThreadPoolExecutor和ScheduledThreadPoolExecutor。

《java.util.concurrent 包源码阅读》09 线程池系列之介绍篇的更多相关文章

  1. 《java.util.concurrent 包源码阅读》 结束语

    <java.util.concurrent 包源码阅读>系列文章已经全部写完了.开始的几篇文章是根据自己的读书笔记整理出来的(当时只阅读了部分的源代码),后面的大部分都是一边读源代码,一边 ...

  2. 《java.util.concurrent 包源码阅读》13 线程池系列之ThreadPoolExecutor 第三部分

    这一部分来说说线程池如何进行状态控制,即线程池的开启和关闭. 先来说说线程池的开启,这部分来看ThreadPoolExecutor构造方法: public ThreadPoolExecutor(int ...

  3. 《java.util.concurrent 包源码阅读》04 ConcurrentMap

    Java集合框架中的Map类型的数据结构是非线程安全,在多线程环境中使用时需要手动进行线程同步.因此在java.util.concurrent包中提供了一个线程安全版本的Map类型数据结构:Concu ...

  4. 《java.util.concurrent 包源码阅读》02 关于java.util.concurrent.atomic包

    Aomic数据类型有四种类型:AomicBoolean, AomicInteger, AomicLong, 和AomicReferrence(针对Object的)以及它们的数组类型, 还有一个特殊的A ...

  5. 《java.util.concurrent 包源码阅读》17 信号量 Semaphore

    学过操作系统的朋友都知道信号量,在java.util.concurrent包中也有一个关于信号量的实现:Semaphore. 从代码实现的角度来说,信号量与锁很类似,可以看成是一个有限的共享锁,即只能 ...

  6. 《java.util.concurrent 包源码阅读》06 ArrayBlockingQueue

    对于BlockingQueue的具体实现,主要关注的有两点:线程安全的实现和阻塞操作的实现.所以分析ArrayBlockingQueue也是基于这两点. 对于线程安全来说,所有的添加元素的方法和拿走元 ...

  7. 《java.util.concurrent 包源码阅读》22 Fork/Join框架的初体验

    JDK7引入了Fork/Join框架,所谓Fork/Join框架,个人解释:Fork分解任务成独立的子任务,用多线程去执行这些子任务,Join合并子任务的结果.这样就能使用多线程的方式来执行一个任务. ...

  8. 《java.util.concurrent 包源码阅读》24 Fork/Join框架之Work-Stealing

    仔细看了Doug Lea的那篇文章:A Java Fork/Join Framework 中关于Work-Stealing的部分,下面列出该算法的要点(基本是原文的翻译): 1. 每个Worker线程 ...

  9. 《java.util.concurrent 包源码阅读》05 BlockingQueue

    想必大家都很熟悉生产者-消费者队列,生产者负责添加元素到队列,如果队列已满则会进入阻塞状态直到有消费者拿走元素.相反,消费者负责从队列中拿走元素,如果队列为空则会进入阻塞状态直到有生产者添加元素到队列 ...

随机推荐

  1. Cygwin - windows系统下运行linux操作 --代替linux虚拟机安装、双系统的繁琐

    我把Cygwin视为Windows用户熟练linxu系统操作的良好途径.它不需要虚拟机.双系统等安装对电脑知识.硬件的要求,只需要基本的软件安装操作即可.以下是安装步骤供小白同胞参考. Cygwin安 ...

  2. ASP.NET没有魔法——ASP.NET MVC使用Area开发一个管理模块

    之前的My Blog提供了列表的展示和文章显示功能,但是所有数据仍然只能通过数据库录入,为了完成最初的角色“作者”的用例,本章将介绍如何使用“Area”实现My Blog的管理功能. 根据功能分离代码 ...

  3. C#连接oracle数据库提示ORA-12154: TNS: 无法解析指定的连接标识符

    C#连接oracle数据库提示ORA-12154: TNS: 无法解析指定的连接标识符如果PLSQL Develope能连接上而用代码无法连接上则可以考虑sqlnet.ora文件中是否有NAMES.D ...

  4. 打包zip下载

    //首先引入的文件为org.apache的切记不是jdk的import org.apache.tools.zip.ZipOutputStream;import org.apache.tools.zip ...

  5. LeetCode 189. Rotate Array (旋转数组)

    Rotate an array of n elements to the right by k steps. For example, with n = 7 and k = 3, the array  ...

  6. express紧急回顾随笔

    四行代码搭建服务器 var express = require('express'); var app = express(); //设定静态路径 所有请求优先在此路径查找 //不要把服务器配置JS文 ...

  7. 排序算法总结(C++版)

    总结下学过的排序算法,方便以后用到. 1.插入排序——将一个记录插入到已排序好的有序表中,从而得到一个新,记录数增1的有序表. void insertSort(int a[],int len) { ; ...

  8. 18个超有趣的SVG绘制动画赏析

    SVG作为时下比较新颖的技术标准,已经建立了很多基于SVG的前端项目.由于SVG在绘制路径上非常灵活,我们将很多网页上的元素使用SVG来绘制而成,有各种人物.小图标.小动画等等.今天我们收集了18个非 ...

  9. Linux学习(十六)VIM

    一.简介 VIM是vi的增强版.VIM是Linux平台上的主要编辑器.基本上所有的文档的新增,修改,保存都需要用到它.所以,掌握VIM是很有必要的. vim的安装非常简单,一条命令就可以了: yum ...

  10. Android 开发笔记___SQLite__优化记住密码功能

    package com.example.alimjan.hello_world; /** * Created by alimjan on 7/4/2017. */ import com.example ...