美文网首页
多线程 -- 线程池

多线程 -- 线程池

作者: Simon_z | 来源:发表于2017-04-10 22:51 被阅读18次

    多线程 -- 线程池

    1. 作用

    • 重用线程, 减少线程创建销毁带来的开销;
    • 限制最先线程并发数目, 避免大量线程之间因相互抢占系统资源而导致的阻塞现象;

    2. 创建与使用

    通常我们通过Executors类提供的工厂方法创建线程池;
    而线程池的实际实现是ThreadPoolExecutor, 它提供一系列的参数来配置线程池;
    我们通过ExecutorService去管理线程池, 用它去提交任务, 关闭线程池; 它是一个接口, ThreadPoolExecutor实现了该接口;
    我们提交任务给线程池去执行, 而任务由Executor(执行器)去提交, Executor是一个接口, ExecutorService又继承了该接口;

    2.1 ThreadPoolExecutor

    线程池的实际实现, 它的构造方法提供了一系列的参数用于我们配置线程池;

      ThreadPoolExecutor(int corePoolSize,
                        int maximumPoolSize,
                        long keepAliveTime,
                        TimeUnit unit,
                        BlockingQueue<Runnable> workQueue,
                        ThreadFactory threadFactory,
                        RejectedExecutionHandler handler);
    
    corePoolSize & maximumPoolSize (核心和最大池大小)

    当新任务在方法 execute(java.lang.Runnable) 中提交时,如果运行的线程少于 corePoolSize,则创建新线程来处理请求,即使其他辅助线程是空闲的。如果运行的线程多于 corePoolSize 而少于 maximumPoolSize,则仅当队列满时才创建新线程;

    keepAliveTime & unit (保持活动时间)

    如果池中当前有多于 corePoolSize 的线程,则这些多出的线程在空闲时间超过 keepAliveTime 时将会终止;
    默认情况下, 核心线程会一直存活, allowCoreThreadTimeOut(boolean)设置为true时, 超时策略同样会作用于核心线程;

    workQueue (工作队列)

    线程池中的工作队列; 通过execute提交的Runnable都会保存在这儿; 具体情况如下:

    • 如果运行的线程少于 corePoolSize,则 Executor 始终首选添加新的线程,而不进行排队。(如果当前运行的线程小于corePoolSize,则任务根本不会存放,添加到queue中,而是直接抄家伙(thread)开始运行)
    • 如果运行的线程等于或多于 corePoolSize,则 Executor 始终首选将请求加入队列,而不添加新的线程
    • 如果无法将请求加入队列,则创建新的线程,除非创建此线程超出 maximumPoolSize,在这种情况下,任务将被拒绝。
    threadFactory

    线程工厂; 为线程池提供Thread对象; 可以自定义ThreadFactory, 为线程池中的thread添加属性;

    RejectedExecutionHandler

    当线程池已经关闭, 或者任务队列已满而无法执行新任务时, execute会调用RejectedExecutionHandler去处理;
    默认情况下, 会直接抛出 RejectedExecutionExecption ;

    hook方法

    可重写的 beforeExecute(Runnable) 和 afterExecute(Throwable) 方法,这两种方法分别在执行每个任务之前和之后调用。
    它们可用于操纵执行环境;例如重新初始化 ThreadLocal、搜集统计信息或添加日志条目。此外,还可以重写方法 terminated() 来执行 Executor 完全终止后需要完成的所有特殊处理;

    3 Executors

    Executors 系统系统的线程池的工厂方法; 可以产生如下几种常用的线程池;

    • newCachedThreadPool 无核心线程,辅助线程无上限, 超时60s的线程池
    • newFixedThreadPool 固定线程数的线程池
    • newSingleThreadExecutor 只有一个线程, 所有任务单个依次执行
    • newScheduledThreadPool 可以提交延迟任务,或者定期任务的线程池
    • newSingleThreadScheduledExecutor

    4 使用方法

    1. 创建一个线程池, 使用Executors中的静态方法创建一个线程池
    2. 调用submit方法提交一个Runnable或者Callable对象
    3. 如果要取消一个任务, 或如果提交的是Callable对象, 就需要保存好返回的Future对象
    4. 当不再提交任何任务时, 调用shutdown方法

    相关文章

      网友评论

          本文标题:多线程 -- 线程池

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