zoukankan      html  css  js  c++  java
  • 线程池

    本文主要是说明线程池的几个类的关系。因为有些东西经常搞混。至于线程池的流程,原理,作用等信息,以后想写的时候再追加吧。

    1. 线程池相关的类

    Executor:

    只有一个execute(Runnable command)方法;

    ExecutorService:

    对Executor接口进行了扩展,增加submit(Callable<T> task),关系线程池,执行一组任务等方法。

    ExecutorService executor = ...;    // 线程池的生成

    Executors:

    它是一个线程池工厂类,里面提供了多个工开发人员快速使用的线程池,如newFixedThreadPool、newCachedThreadPool、newScheduledThreadPool等,此外它还可以返回一个包装过的ExecutorService,是线程池的配置不可以被更改。(通过调用unconfigurableExecutorService(ExecutorService executor))

    TheadPoolExecutor:

    创建线程池核心类。或许之前,你创建线程池的时候经常是直接调用Executors的静态方法,但是这个有弊端,你没有明确你对创建的线程池的需求,比如说核心线程数,最大线程数,线程工厂,排队对列等。我们再创建线程池的时候,应该使用TheadPoolExecutor这个类,使用它的构造方法,明确指定线程池配置的核心参数。这一点也是阿里巴巴开发规范手册中提到的。

    Runnable、Callable:

    为了后面需要,说明一下它们的不同点。

    Runnable没有返回值,并且不可以抛出异常;Callable有返回值,并且可以抛出异常。

    Future、FutureTask:

    线程池提交完任务后,都会返回一个Future。下面,通过代码看一下它们的不同。

     1 interface ArchiveSearcher { String search(String target); }
     2  class App {
     3    ExecutorService executor = ...
     4    ArchiveSearcher searcher = ...
     5    void showSearch(final String target)
     6        throws InterruptedException {
     7      Future<String> future
     8        = executor.submit(new Callable<String>() {
     9          public String call() {
    10              return searcher.search(target);
    11          }});
    12      displayOtherThings(); // do other things while searching
    13      try {
    14        displayText(future.get()); // use future
    15      } catch (ExecutionException ex) { cleanup(); return; }
    16    }
    17  }

    FutureTask实现了Future接口,它还实现了Runnable接口。上面的构造方法可以用下面的形式进行替换:

    1  FutureTask<String> future =
    2    new FutureTask<String>(new Callable<String>() {
    3      public String call() {
    4        return searcher.search(target);
    5    }});
    6  executor.execute(future);

    (Future和FutureTask的代码,摘自java api 8)

    CompletionService、ExecutorCompletionService:

    顾名思义,完成服务,它依靠一个单独的Exetuor来执行任务,CompletionService只管理内部完成的队列任务。

    我们看下面的示例:

    使用ExecutorService

     1 ExecutorService executorService = Executors.newFixedThreadPool(4);
     2 List<Future> futures = new ArrayList<Future<Integer>>();
     3 futures.add(executorService.submit(A));
     4 futures.add(executorService.submit(B));
     5 futures.add(executorService.submit(C));
     6 futures.add(executorService.submit(D));
     7 
     8 Then we can iterate over the list to get the computed result of each future:
     9 for (Future future:futures) {
    10     Integer result = future.get();     // 结果的顺序就是提交的顺序,taskB完成了,但是taskA未完成,那么就会在taskA那里阻塞到完成为止。
    11     // rest of the code here.
    12 }

    使用CompletionService

     1 ExecutorService executorService = Executors.newFixedThreadPool(4);
     2         CompletionService executorCompletionService= new ExecutorCompletionService<>(executorService );
     3         //Then again we can submit the tasks and get the result like:
     4         executorCompletionService.submit(A);
     5         executorCompletionService.submit(B);
     6         executorCompletionService.submit(C);
     7         executorCompletionService.submit(D);
     8 
     9         for (int i=0; i<4; i++) {
    10             Integer result = executorCompletionService.take().get();  // 哪个先完成就先获取哪个的结果,跟任务提交顺序无关。
    11             // Some processing here
    12         }
  • 相关阅读:
    MySQL中的内置系统函数
    Mysql导出表结构及表数据 mysqldump用法
    MySQL事务处理案例演示
    mysql中int、bigint、smallint 和 tinyint的区别详细介绍
    mysql 获取上个月,这个月的第一天或最后一天
    ★MySQL一些很重要的SQL语句
    remix的使用
    nodejs部署智能合约的方法-web3 0.20版本
    js同步-异步-回调
    ganache与metamask
  • 原文地址:https://www.cnblogs.com/lihao007/p/10350739.html
Copyright © 2011-2022 走看看