Executors框架

老马说编程

思想

将"任务的提交"和"任务的执行"相分离,
执行服务 封装了任务执行的细节(线程创建、任务调度、线程关闭),
任务提交者而言,关注于任务本身(提交任务、获取结果、取消任务)

Future

提交者, 提交任务以后 得到一个Future, 用它可以去掉任务,获得结果 等

public interface Future<V> {

    boolean cancel(boolean mayInterruptIfRunning);

    boolean isCancelled();

    boolean isDone();

//取结果
    V get() throws InterruptedException, ExecutionException;
    V get(long timeout, TimeUnit unit) throws InterruptedException, 

        ExecutionException, TimeoutException;
}

get方法,任务最终大概有三个结果:

  • 正常完成
    返回其执行结果,如果任务是Runnable且没有提供结果,返回null
  • 任务执行抛出了异常,
    将异常包装为ExecutionException重新抛出,通过异常的getCause方法可以获取原异常
  • 任务被取消了,
    抛出异常CancellationException

最简用法示例

 public static void main(String[] args) throws InterruptedException,ExecutionException {

        //创建了一个任务执行服务 
        ExecutorService executor = Executors.newSingleThreadExecutor();

        //不管ExecutorService是如何创建的,对使用者而言,用法都一样
        Future<Integer> future = executor.submit(new Task());

        // 执行其他任务
        System.out.println(future.get());
    
        //关闭任务执行服务,不再接受新任务,
        //但已提交的任务会继续执行
        executor.shutdown();
    }

使用了工厂类Executors创建了一个任务执行服务(Executors可创建多种执行服务,对任务提交者而言,都是一样使用)
关闭方法除了shutdown, 还有shutdownNow,
shutdownNow:马上终止,对于正在执行的任务,调用线程的interrupt方法尝试中断(不一定能成)会返回已提交但尚未执行的任务列表

ExecutorService接口

主要实现类是ThreadPoolExecutor,基于线程池的实现
继承最基本的Executor

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

  //提交任务
   <T> Future<T> submit(Callable<T> task);
   <T> Future<T> submit(Runnable task, T result);
   Future<?> submit(Runnable task);//异步任务的最终返回值为null


//不接受新任务
    void shutdown();
//已提交的都尽量停  返回没执行的
    List<Runnable> shutdownNow();
    boolean isShutdown();
    boolean isTerminated();
    boolean awaitTermination(long timeout, TimeUnit unit)
        throws InterruptedException;

//全部执行完返回
    <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;
                   
       
}


invokeAll使用例子:

 public static void main(String[] args) throws InterruptedException {
        
        //创建了一个线程池,这样使得多个任务可以并发执行
        ExecutorService executor = Executors.newFixedThreadPool(10);
        
        //2个任务
        String url1 = "http://www.cnblogs.com/swiftma/p/5396551.html";
        String url2 = "http://www.cnblogs.com/swiftma/p/5399315.html";
        Collection<UrlTitleParser> tasks = Arrays.asList(
                new UrlTitleParser[] {
                        
                        new UrlTitleParser(url1), 
                        new UrlTitleParser(url2) 
                });
        
       //提交任务集合, 超过10秒就异常
        List<Future<String>> results = executor.invokeAll(tasks, 10, TimeUnit.SECONDS);
            
        for (Future<String> result : results) {
            try {
                                //取结果 会等所有任务都完成 才能拿
                System.out.println(result.get());
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
        }
       

        executor.shutdown();
    }

原理

自制简易版Executor

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 本文是我自己在秋招复习时的读书笔记,整理的知识点,也是为了防止忘记,尊重劳动成果,转载注明出处哦!如果你也喜欢,那...
    波波波先森阅读 13,914评论 4 56
  • 一、wait--notify--sleep Object obj = new Object(); obj.wait...
    fe0180bd6eaf阅读 2,812评论 0 1
  • 为什么使用线程池 当我们在使用线程时,如果每次需要一个线程时都去创建一个线程,这样实现起来很简单,但是会有一个问题...
    闽越布衣阅读 9,797评论 10 45
  • 带孩子是件很容易的事情,但是把孩子教育好,很难,难在哪里?言传身教,持之以恒,耐心教育。为什么?因为自己是不够优秀...
    如恒阅读 1,274评论 1 2
  • 前面的文章里面有关于自定义验证码视图OC相关的代码,在swift_3中,大体上的结构都是相同的,只是因为swift...
    hoggenWang阅读 3,443评论 0 0

友情链接更多精彩内容