【初识】-JUC·Executor框架

2,575 阅读4分钟

前言

多线程和并发这两个东西真的是向往已久,总是有一种神秘的感觉,想去探索一波,又担心水平不够无法驾驭。想以读书笔记的方式来写,但是又觉得缺少自己的一些思考;但是在没有足够并发编程经验的情况下又没法去写出很深刻的东西,毕竟没有踩过坑。所以在阅读spring源码的同时,也想抽点时间来看一看JUC的东西,关于这块只能说是记录自己学习JUC的一个过程,尝试用一些具体的代码demo来加深理解。所以就把本系列写成《【 初识】-JUC·XXXX》,用来让自己打开并发编程的大门。

JUC

JUC即java.util.concurrent;也就是java提供的并发包。JUC中从包结构上来看主要是:

  • java.util.concurrent

    在这个包下面主要是线程池、并发集合以及一些并发工具类。线程池相关是围绕Excetor框架来构建;这也是本文下面部分的重点。

  • java.util.concurrent.atomic

    这个包下面是一些原子操作类,算是并发辅助工具类,基本实现依赖于CAS;

  • java.util.concurrent.locks

    这个从名字就可以知道它的作用,就是提供锁。

JUC各个模块的类

  • 整体框架

  • atomic

  • locks

  • 并发集合

  • 并发工具

  • forkJoin

    fork-join在JUC中有下面三个类:

    public class ForkJoinPool extends AbstractExecutorService
    
    public abstract class ForkJoinTask<V> implements Future<V>, Serializable
    
    public class ForkJoinWorkerThread extends Thread
    

Future

Future提供了可以获取异步执行结果的方法,区别于Runnable的run方法,run是不提供返回结果的。

public interface Future<V> {
    //取消
    boolean cancel(boolean mayInterruptIfRunning);
    //如果任务完成前被取消,则返回true。
    boolean isCancelled();
    //如果任务执行结束,无论是正常结束或是中途取消还是发生异常,都返回true。
    boolean isDone();
    //获取异步执行的结果,如果没有结果可用,此方法会阻塞直到异步计算完成。
    V get() throws InterruptedException, ExecutionException;
    //获取异步执行结果,如果没有结果可用,此方法会阻塞,但是会有时间限制,
    //如果阻塞时间超过设定的timeout时间,该方法将抛出异常。
    V get(long timeout, TimeUnit unit) throws InterruptedException, 
    ExecutionException, TimeoutException;
}

Callable

声明了一个名称为call()的方法,同时这个方法可以有返回值V,也可以抛出异常

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

关于Callable和Future的使用一般情况下都是结合我们的线程池来使用的。

Executor

Executor接口是线程池实现的顶级接口,其和spring中的BeanFactory所承担的角色差不多,就是提供顶级的功能约束,具体实现交于不同子类来完成。

public interface Executor {
    /**
     * Executes the given command at some time in the future.  The command
     * may execute in a new thread, in a pooled thread, or in the calling
     * thread, at the discretion of the <tt>Executor</tt> implementation.
     *
     * @param command the runnable task
     * @throws RejectedExecutionException if this task cannot be
     * accepted for execution.
     * @throws NullPointerException if command is null
     */
    void execute(Runnable command);
}

下面是JUC中Executor框架的整体结构:

ExecutorService

public interface ExecutorService extends Executor {
    //关闭线程池
    void shutdown();
    
    List<Runnable> shutdownNow();
    //是否为Shutdown状态
    boolean isShutdown();
    //是否为Terminated状态
    boolean isTerminated();
    
    //超过超时时间时,会监测ExecutorService是否已经关闭
    //若关闭则返回true,否则返回false。
    //一般情况下会和shutdown方法组合使用。
    boolean awaitTermination(long timeout, TimeUnit unit)
        throws InterruptedException;
    
    //返回一个Future对象,参数接收的是一个Callable的实现
    //Callable接口中的call()方法有一个返回值,可以返回任务的执行结果
    //区别于Runnable接口中的run()方法(void修饰,没有返回值)。
    <T> Future<T> submit(Callable<T> task);
    
    <T> Future<T> submit(Runnable task, T result);
    //返回一个Future对象,通过返回的Future对象,我们可以检查提交的任务是否执行完成了。 
    Future<?> submit(Runnable task);
    
    //返回一个Future的List,其中对应着每个Callable任务执行后的Future对象。
    <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;
        
        
    //接收参数是一个Callable的集合,
    //返回的是所有Callable集合任务中某一个任务的执行结果
    <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 再Executor接口的基础上扩展了对线程池状态的控制以及提交任务执行的超时控制。线程池的基本功能还不够完善,不能真正的具备处理具体业务的能力(毕竟是个接口,O(∩_∩)O哈哈~)。

开个篇,慢慢学~