金华
切换分站
免费发布信息
    金华Java 并发类库提供的线程池有哪几种-分别有什么特点
    分享  | 2019-09-03 16:12:27发布 信息编号:842411
  • 置顶
  • 收藏  |
  • 删除  |
  • 修改  |
  • 举报  |
金华Java 并发类库提供的线程池有哪几种-分别有什么特点
  • 金华Java 并发类库提供的线程池有哪几种-分别有什么特点
  • 金华Java 并发类库提供的线程池有哪几种-分别有什么特点
  • 金华Java 并发类库提供的线程池有哪几种-分别有什么特点
  • 学费:88元
  • 地址:婺城区 城北街道 220.188.55.* 浙江省金华市电信
    • Q Q:2885078129QQ在线交谈
    • 联系人:上元李老师
    • 电话:1875769**** 点击查看完整号码
      • 便民网提醒您:让你提前汇款,或者价格明显低于市价,均有骗子嫌疑,不要轻易相信。
  • 信息详情
金华Java 并发类库提供的线程池有哪几种-分别有什么特点
金华Java 并发类库提供的线程池有哪几种-分别有什么特点

通常开发者都是利用Executors提供的通用线程池创建方法,去创建不同配置的线程池,主要区别在于不同的ExecutorService类型或者不同的初始参数。

  Executors目前提供了5种不同的线程池创建配置:

  (1)、newCachedThreadPool(),它是一种用来处理大量短时间工作任务的线程池,具有几个鲜明特点:它会试图缓存线程并重用,当无缓存线程可用时,就会创建新的工作线程;如果线程闲置的时间超过60秒,则被终止并移出缓存;长时间闲置时,这种线程池,不会消耗什么资源。其内部使用SynchronousQueue作为工作队列。

  (2)、newFixedThreadPool(int nThreads),重用指定数目(nThreads)的线程,其背后使用的是无界的工作队列,任何时候最多有nThreads个工作线程是活动的。这意味着,如果任务数量超过了活动队列数目,将在工作队列中等待空闲线程出现;如果有工作线程退出,将会有新的工作线程被创建,以补足指定的数目nThreads。

  (3)、newSingleThreadExecutor(),它的特点在于工作线程数目被限制为1,操作一个无界的工作队列,所以它保证了所有任务的都是被顺序执行,最多会有一个任务处于活动状态,并且不允许使用者改动线程池实例,因此可以避免其改变线程数目。

  (4)、newSingleThreadScheduledExecutor()和newScheduledThreadPool(int corePoolSize),创建的是个ScheduledExecutorService,可以进行定时或周期性的工作调度,区别在于单一工作线程还是多个工作线程。

  (5)、newWorkStealingPool(int parallelism),这是一个经常被人忽略的线程池,Java 8才加入这个创建方法,其内部会构建ForkJoinPool,利用Work-Stealing算法,并行地处理任务,不保证处理顺序。

  线程池的内部工作原理?

  (1)、**工作队列负责存储用户提交的各个任务,这个工作队列,可以是容量为0的SynchronousQueue(如:newCachedThreadPool),也可以是LinkedBlockingQueue(如newFixedThreadPool);

  private final BlockingQueue<Runnable>workQueue;

  (2)、**内部的“线程池”,这是指保持工作线程的集合,线程池需要在运行过程中管理线程创建、销毁。例如,对于带缓存的线程池,当任务压力较大时,线程池会创建新的工作线程。当业务压力退去,线程池会在闲置一段时间后结束线程;

  //线程池的工作线程被抽象为静态内部类Worker,基于AQS实现。

  private final HashSet<Worker>workers=new HashSet<>();

  (3)、ThreadFactory提供上面所需要的创建线程逻辑;

  (4)、**如果任务提交时被拒绝,比如线程池已经处于SHUTDOWN状态,需要为其提供处理逻辑,Java标准库提供了类似ThreadPoolExecutor、AbortPolicy等默认实现,也可以按照实际需求自定义。

  线程池的基本组成部分

  从上面的分析,就可以看出线程池的几个基本组成部分,基本都体现在线程池的构造函数中。如:

  public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue<Runnable>workQueue,ThreadFactory threadFactory,RejectedExecutionHandler handler)

  (1)、corePoolSize:所谓的核心线程数,可以大致理解为长期驻留的线程数目(除非设置了allowCoreThreadTimeOut)。对于不同的线程池,这个值可能会有很大区别,比如newFixedThreadPool会将其设置为nThreads,而对于newCachedThreadPool则是为0。

  (2)、maximumPoolSize,顾名思义,就是线程不够时能够创建的最大线程数。同样进行对比,对于newFixedThreadPool,当然就是nThreads,因为其要求是固定大小,而newCachedThreadPool则是Integer.MAX_VALUE。

  (3)、keepAliveTime和TimeUnit,这两个参数指定了额外的线程能够闲置多久,显然有些线程池不需要它。

  (4)、workQueue,工作队列,必须是BlockingQueue。

  通过配置不同的参数,我们就可以创建出行为大相径庭的线程池,这就是线程池高度灵活性的基础。

  线程池大小的选择策略:

  ①、如果我们的任务主要是进行计算,那么就意味着CPU的处理能力是稀缺的资源,我们能够通过大量增加线程数提高计算能力吗?往往是不能的,如果线程太多,反倒可能导致大量的上下文切换开销。所以,这种情况下,通常建议按照CPU核的数目N或者N+1。

  ②、如果是需要较多等待的任务,例如I/O操作比较多,可以参考:

  线程数=CPU核数×(1+平均等待时间/平均工作时间)

  上面是仅仅考虑了CPU等限制,实际还可能受各种系统资源限制影响。不要把解决问题的思路全部指望到调整线程池上,很多时候架构上的改变更能解决问题。

  请介绍类加载过程,什么是双亲委派模型?

  一般来说,我们把Java的类加载过程分为三个主要步骤:加载、链接、初始化。

  (1)、加载阶段(Loading),它是Java将字节码数据从不同的数据源读取到JVM中,并映射为JVM认可的数据结构(Class对象);加载阶段是用户参与的阶段,我们可以自定义类加载器,去实现自己的类加载过程。

  (2)、链接(Linking),这是核心的步骤,把原始的类定义信息平滑地转化入JVM运行的过程中。这里可进一步细分为三个步骤:

  验证(Verification),JVM需要核验字节信息是符合Java虚拟机规范的;

  准备(Preparation),创建类或接口中的静态变量,并初始化静态变量的初始值。但这里的“初始化”和下面的显式初始化阶段是有区别的,侧重点在于分配所需要的内存空间,不会去执行的JVM指令。

  解析(Resolution),在这一步会将常量池中的符号引用(symbolic reference)替换为直接引用。

  (3)、初始化阶段(initialization),这一步真正去执行类初始化的代码逻辑。

金华Java 并发类库提供的线程池有哪几种-分别有什么特点
金华Java 并发类库提供的线程池有哪几种-分别有什么特点
联系我时,请说是在金华便民网看到的,谢谢!

金华Java 并发类库提供的线程池有哪几种-分别有什么特点
金华Java 并发类库提供的线程池有哪几种-分别有什么特点
金华Java 并发类库提供的线程池有哪几种-分别有什么特点

  • 您可能感兴趣
查看更多
    温馨提示:本页信息由用户及第三方发布,真实性、合法性由发布人负责,请仔细甄别。