美文网首页
FutureTask,ThreadPoolExecutor

FutureTask,ThreadPoolExecutor

作者: 郑捡书 | 来源:发表于2019-04-16 18:32 被阅读0次
    FutureTask_UML
    FutureTask设计解释
    1.正真开启线程是Thread类(构造函数接受Runnable类型的参数),而Thread又继承了Runnable,执行的就是run()方法。
    2.Runnable是一个任务体。
    3.Callable也是一个任务体。(相较于Runnable能返回结果而已)
    3.Future可以视为一个工具类
    
    源码分析
    // FutureTask实现了Runnable类,即可作为任务体传递给Thread执行
    // 重写run()方法,最终都是执行Callable的call()方法
        public void run() {
                // 虚假代码.....
                Callable<V> c = callable;
                result = c.call();              
        }
    
    // 如果接收Runnable呢,其实就是做了一个适配转换
     public FutureTask(Runnable runnable, V result) {
            this.callable = Executors.callable(runnable, result);
     }
    
    // 可以忽略不看,就是封多了一层方法而已
     public static <T> Callable<T> callable(Runnable task, T result) {
            if (task == null)
                throw new NullPointerException();
            return new RunnableAdapter<T>(task, result);
        }
    
    // 正在的转换
    private static final class RunnableAdapter<T> implements Callable<T> {
            private final Runnable task;
            private final T result;
            RunnableAdapter(Runnable task, T result) {
                this.task = task;
                this.result = result;
            }
            public T call() {
                // 执行了Runnable方法的run()方法,返回值类型为传入的泛型
                task.run();
                return result;
            }
        }
    
    FutureTask任务状态流转
    1. NEW:当FutureTask被初始创建的时候的状态。
    2. COMPLETING和NORMAL:当任务被执行完毕,FutureTask会将执行结果设置给FutureTask的outcome属性,在设置之前会将FutureTask的状态修改为COMPLETING,在设置之后会将FutureTask的状态修改为NORMAL。
    3. EXCEPTIONAL:当任务在被执行的过程中抛了异常,FutureTask会将异常信息设置给FutureTask的outcome属性,在设置之前会将FutureTask的状态修改为COMPLETING,在设置之后会将FutureTask的状态修改为EXCEPTIONAL。
    4. CANCELLED:当外部想要取消任务,而又不允许当任务正在执行的时候被取消的时候会将FutureTask的状态修改为CANCELLED。
    5. INTERRUPTING和NTERRUPTED:当外部想要取消任务,同时允许当任务正在执行的时候被取消的时候,会先将FutureTask的状态设置为INTERRUPTING,然后设置执行任务的线程的中断标记位,最后将Future的状态设置为INTERRUPTED。
    FutureTask的状态流转可能流程
    NEW—>COMPLETING—>NORMAL(任务执行正常)。
    NEW—>COMPLETING—>EXCEPTIONAL(任务执行异常)。
    NEW—>CANCELLED(不允许执行中的取消)。
    NEW—>INTERRUPTING—>INTERRUPTED(允许执行中的取消)。
    
    Future相关方法解析
    // 返回值 :已完成或者已取消的前提下调用将返回false;true表示取消成功(任务将不再被执行,)。
    // 参数:true表示停止正在执行的任务;false表示不打断正在执行的任务,任务可以正常完成;
     boolean cancel(boolean mayInterruptIfRunning);
    
      // 重点示例:先调用了cancel(参数无论是true/false),这时候再启动线程任务将不被执行
     FutureTask futureTask = new FutureTask(new Runn5());
     futureTask.cancel(true);
     Thread thread = new Thread(futureTask);
     thread.start();
    
    // 其实就是cancel()的返回值
     boolean isCancelled();
    
    // 任务被取消或者已完成,以及发生异常终止,都将返回true
     boolean isDone();
    
    // 线程阻塞获取结果
    V get() throws InterruptedException, ExecutionException,CancellationException;
    
    // 线程 阻塞获取结果,传入等待时长,超过等待时长抛出TimeoutException
    V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, CancellationException,TimeoutException;
    
    
    ThreadPoolExecutor
    ThreadPoolExecutor_UML

    按照默认线程池是实现ExecutorService接口的,按照ExecutorService接口定义的行为,我们可以将Runnable或Callable任务提交到线程池让其去被执行,而被提交的Runnable或Callable任务都会被包装成FutureTask,丢到任务队列,由线程池的工作线程去执行。使用线程池不仅可以提高应用的响应时间,还可以避免”java.lang.OutOfMemoryError: unable to create new native thread” 之类的错误。

    ExecutorService方法解析
    // 提交任务执行,在调用此方法前调用了shutdown()则会报RejectedExecutionException异常
    <T> Future<T> submit(Callable<T> task);
    // 线程池会停止接受新的任务,但会完成已提交的任务
    void shutdown();
    // 返回已提交还没执行的线程,对于正在执行的任务一般会调用interrupt方法尝试中断
    List<Runnable> shutdownNow();
    // 判断是否执行了shutdown或者shutdownNow()方法
    boolean isShutdown();
    //获取所有任务是否已经结束,当调用shutdown或者shutdownNow方法后,并且所有提交的任务完成后返回为true
    boolean isTerminated();
    // 阻塞等待所有任务结束,可以设置timeout,如果超时了所有任务还未完成则返回false,反之
    boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException;
    // 批量提交任务,整个过程为阻塞,是因为内部执行了Future.get(),所有任务都执行完毕后才返回。
    <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;
    

    相关文章

      网友评论

          本文标题:FutureTask,ThreadPoolExecutor

          本文链接:https://www.haomeiwen.com/subject/ikatwqtx.html