线程池

作者: _Once1 | 来源:发表于2018-05-27 21:28 被阅读0次

    线程
    使用方法

    • 继承Thread类,重写run()方法
    • 实现Runnable接口,实现run()方法,在使用时,需要new Thread(new MyRunnable()).start()
    • 实现Callable接口,实现call()方法,该方法执行后,会有返回值;并且可能抛出异常;并且执行后,可以得到一个Future对象

    并行和并发

    • 并行:真正意义上的同时执行
    • 并发:存在抢占cup资源和等待现象,只是同时运行的假象

    线程池

    线程池.png
    Executor
    线程池的概念来源于Java中的Executor接口,其只有一个execute()方法。ExecutorService接口实现了该接口,增加了一些常用方法,一般所说的线程池接口,即指ExecutorService接口
    真正的实现为ThreadPoolExecutor类

    ThreadPoolExecutor
    看一个常用的构造方法:

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

    参数说明:

    1. corePoolSize
      核心线程数,默认其会一直存活;当指定其allowCoreThreadTimeOut属性为true,则当闲置核心线程超过keepAliveTime时,会被终止
    2. maximumPoolSize
      所能容纳最大线程数,超过该值,则后续新任务会被阻塞;
      值 = 核心线程数 + 非核心线程数
    3. keepAliveTime
      非核心线程超时时间;若设置了上述属性,则同样作用于核心线程
    4. unit
      单位,不多说
    5. workQueue
      execute方法提交的runnable对象会存储在该队列中
    6. threadFactory
      为线程池提供新建线程的功能

    执行任务原则

    1. 优先核心线程
    2. 线程数量大于等于核心线程数量,则任务被插入任务队列中排队等待
    3. 若2中无法插入(队列已满),若线程数量未达到线程池规定的最大值,则启动非核心线程执行
    4. 若3中已经达到最大值,则拒绝执行此任务,并调用rejectdExecution方法通知调用者(其中一个构造参数中可传入该对象)
      简而言之,顺序为:核心线程-任务队列-非核心线程

    如何提交任务?
    这里提供了两种方法:

    • execute(runnable); 该方法无法得到返回值
    • Future future submit(callable); 执行一个任务,返回一个future对象,可以通过future.get()去获取返回值,get方法会一直阻塞,直到请求成功;
      另外,get方法还可以设置一个超时时间,若超时还未完成,则会抛出异常,我们这时只需要catch异常实现自己的逻辑即可

    常见分类

    • FixedThreadPool
      只有核心线程,且不会被回收,任务队列大小无限制
    • CachedThreadPool
      只有非核心线程,超时时长为60s;适合执行大量耗时少的任务
      其他两种见导图

    参考这位兄弟的博客

    相关文章

      网友评论

          本文标题:线程池

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