zoukankan      html  css  js  c++  java
  • 那些年读过的书《Java并发编程实战》和《Java并发编程的艺术》三、任务执行框架—Executor框架小结

    School《Java并发编程实战》和《Java并发编程的艺术》           Executor框架小结

    1、在线程中如何执行任务

          (1)任务执行目标:

    在正常负载情况下,服务器应用程序要表现出良好的吞吐率和快速的响应性。在负载过载的情况下,应用程序的性能应该是逐渐减低的,而不是直接失败。

    要实现高吞吐率和快速的响应,就应该选择清晰的任务边界和明确的任务执行策略。

          (2)任务执行策略有:

    1)单线程串行执行任务:缺点:无法提高服务器应用程序的吞吐率和快速响应速度

    2)根据任务显示创建线程:缺点:无限创建线程太消耗资源;线程的创建和消耗开销高;易造成系统不稳定

    3)利用线程池显示创建线程:

    2、任务执行框架-Executor框架

                早期Java的线程既是工作单元又是执行机制,而从JDK5开始,使用Runnable和Callable表示工作单元(任务)而由Executor框架负责提供任务的执行机制。

                Executor框架封装了多种不同的任务执行策略,实现了任务的提交与任务的执行的解耦,还提供了对线程生命周期的管理的支持等。

                任务的表示:Runnable和Callable或者FutureTask

    (1)Executor框架类图和Java队列类图

    Executor类图java类图

     

             (2)线程池

    线程池

    特点

    默认等待队列

    适用场景

    ThreadPoolExecutor

    newFixedThreadPool

    创建固定长度的线程池 返回通用的
    ThreadPoolExecutor

    无界队列LinkedBlockingQueue

    适用于为了满足资源管理的需求,而需要限制当前线程数量的场景
    适用于负载比较中的服务器

    newCachedThreadPool

    创建可缓存的线程池,空闲线程会被回收掉,线程池规模不受限制(即线程池大小不限制)返回通用的ThreadPoolExecutor

    SynchronousQueue

    适用于执行很多短期异步任务的小程序或者负载较轻的服务器

    newSingleThreadExecutor

    单线程的Executor,创建当个工作者线程来执行任务。
    能确保按照任务队列中的顺序执行任务 返回通用的ThreadPoolExecutor

    无界队列LinkedBlockingQueue

    适用于需要保证顺序执行各个任务,并且在任意时间点不会有多个线程活动的场景

    ScheduleThreadPoolExecutor

    newScheduledThreadPool

    创建固定的线程池并且以延迟或定时的方式来执行任务
    返回ScheduledThreadPoolExecutor

    无界阻塞队列DelayQueue

    适用于需要多个线程在后台执行周期性任务,同事为了满足资源管理的需求而现在后台线程的数量的应用场景
    适用于需要定时执行任务的场景

    newSingleThreadScheduleThreadPool

    创建单个线程以顺序延迟或者定式的方式执行任务
    返回ScheduledThreadPoolExecutor

    无界阻塞队列DelayQueue

    适用于需要单个线程顺序执行周期性任务的场景

              (3)Executor的生命周期(ExecutorService的接口)

    Executor通过扩展ExecutorService接口新增了执行服务的生命周期管理方法,

    ExecutorService的生命周期有3种状态:运行,关闭,已终止

    ExecutorService接口方法介绍

    方法名称

    作用

    返回参数

    注意事项

    shutdown() 关闭服务,执行平缓的的关闭过程,不再接受新的任务,同时等待所有的任务执行完成(包括已提交但未执行的任务); void  
    shutdownNow() 立即关闭,并取消所有任务包括正在执行的和未执行的,然后返回已提交但未执行的任务(不包括那些正在执行被关闭的任务); List<Runnable>  
    isShutdown(): 如果此执行程序已关闭,则返回 true boolean  
    isTerminated(): 如果关闭后所有任务都已完成,则返回 true。注意,除非首先调用 shutdown 或 shutdownNow,否则 isTerminated 永不为 true。 boolean  
    awaitTermination(long timeout,TimeUnit unit) 等待(阻塞)直到关闭或最长等待时间或发生中断
    如果此执行程序终止,则返回 true;如果终止前超时期满,则返回 false
    boolean  

    execute(Runnable )

    提交一个 Runnable 任务用于执行 void  
    submit(Runnable ) 提交一个 Runnable 任务用于执行,并返回一个表示该任务的 Future。该 Future 的 get 方法在成功完成时将会返回给定的结果。

    Future<?> 

     
    submit(Callable<T> ) 提交一个返回值的任务用于执行,返回一个表示任务的未决结果的 Future。该 Future 的 get 方法在成功完成时将会返回该任务的结果。

    Future<T>

     

    invokeAll(Collection<? extends Callable<T>> tasks,long timeout,TimeUnit unit)

    执行给定的任务,当所有任务完成或超时期满时(无论哪个首先发生),返回保持任务状态和结果的 Future 列表。返回列表的所有元素的 Future.isDone() 为 true。一旦返回后,即取消尚未完成的任务。
    注意,可以正常地或通过抛出异常来终止已完成 任务。如果此操作正在进行时修改了给定的 collection,则此方法的结果是不确定的。
    List<Future<T>>
    表示任务的 Future 列表,列表顺序与给定任务列表的迭代器所生成的顺序相同。
         如果操作未超时,则已完成所有任务。如果确实超时了,则某些任务尚未完成。

    注意1:该方法会一直阻塞直到所有任务完成或超时。
    注意2:如果确实超时了,则某些任务尚未完成。【那么这些尚未完成的任务应该被系统取消】

    invokeAll(Collection<? extends Callable<T>> tasks)

    执行给定的任务,当所有任务完成时,返回保持任务状态和结果的 Future 列表。返回列表的所有元素的 Future.isDone() 为 true。
        注意,可以正常地或通过抛出异常来终止已完成 任务。如果正在进行此操作时修改了给定的 collection,则此方法的结果是不确定的。

    List<Future<T>>

    执行给定的任务,当所有任务完成时,返回保持任务状态和结果的 Future 列表。返回列表的所有元素的 Future.isDone() 为 true。
        注意,可以正常地或通过抛出异常来终止已完成 任务。如果正在进行此操作时修改了给定的 collection,则此方法的结果是不确定的。

    该方法会一直阻塞直到所有任务完成。

               (3)ScheduledThreadPoolExecutor实现延迟任务与周期任务

                 1)比较实现延迟任务与周期任务的两种方法:

    特点

    适用情况

    Timer a.执行所有定时任务时只创建一个线程,任务执行时间过长时破坏其他定时任务的定时精确性
    b.不能处理不捕获未处理异常,遇到未检查异常时将终止定时任务,造成“线程泄露”
    c.基于绝对时间而不是相对时间的调度机制,任务的执行对系统时钟变化很敏感
    少用
    ScheduledThreadPoolExecutor 能够正确处理执行任务过程中出现的异常
    b.基于相对时间的调度
    推荐使用

                 2)如何构建自己的调度服务

    使用DelayQueue为ScheduledThreadPoolExecutor提供调度功能。DelayQueue管理者一组Delayed对象,每个Delayed对象都有一个相应的延迟时间,每个Delayed对象逾期后才能从DelayQueue中执行take操作。

    3、如何提高程序的并行性?找出同构并发执行任务

          (1)任务的表示

    Runnable:

    Callable:可以返回任务执行的结果

          (2)同构任务与异构任务

    同构任务:并发执行性能提升少

    异构任务:并发执行性能提升多

          (3)Future与CompletionService

    Future:作为单个计算句柄

    CompletionService:作为一组计算的句柄,CompletionService将Executor和BlockingQueue的功能融合在一起。

    CopletionService<ImageData> completionService=new ExecutorCompletService(executor);

    completionService.submit(callable);

    completionService.take();

          (4)Future.get()与Future.get(TimeOut,TimeUnit)

    Future.get() 任务不设时限

    Future.get(TimeOut,TimeUnit)为任务设置时限

          (5)Executor.invokeAll(List<Task>,TimeOut,TimeUnit)

    将多个任务提交到ExecutorService并获得一组结果。

    4、如何终止线程

    5、Java中的线程池

    6、Java中的并发工具类

    7、并发编程实践

  • 相关阅读:
    java面试②基础部分
    java面试①整体流程
    Mysql加锁过程详解(6)-数据库隔离级别(2)-通过例子理解事务的4种隔离级别
    Mysql加锁过程详解(6)-数据库隔离级别(1)
    CV3——学习笔记-实战项目(上):如何搭建和训练一个深度学习网络
    CV2——学习笔记-图像分类
    CV1——学习笔记
    思无邪
    C++学习笔记
    操作系统——学习笔记
  • 原文地址:https://www.cnblogs.com/wshcn/p/7118639.html
Copyright © 2011-2022 走看看