中都

风习袅袅,盈水展千华,飞檐亭角清铃响。犹记当初,你回眸莞尔,一笑倾城百日香。

博客园 首页 新随笔 联系 订阅 管理
Java 里面线程池的顶级接口是 Executor,但是严格意义上讲 Executor 并不是一个线程池,而只是一个执行线程的工具。真正的线程池接口是 ExecutorService。

一、线程池的作用

优点:
  1. 避免大量线程之间相互的抢占资源导致的阻塞现象;
  2. 减少线程的创建和销毁带来的开销提升性能;
  3. 提高响应速度。当任务到达时,任务可以不需要等到线程创建就能立即执行;
  4. 提高线程的可管理性。线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控;
 
也就是线程复用、控制最大并发数、管理线程
 
 

线程复用

每一个 Thread 的类都有一个 start 方法。 当调用 start 启动线程时 Java 虚拟机会调用该类的 run方法。 那么该类的 run() 方法中就是调用了 Runnable 对象的 run() 方法。 我们可以继承重写Thread 类,在其 start 方法中添加不断循环调用传递过来的 Runnable 对象。 这就是线程池的实现原理。循环方法中不断获取 Runnable 是用 Queue 实现的,在获取下一个 Runnable 之前可以是阻塞的。
 
ThreadPoolExecutor 的构造方法主要参数:
  1. corePoolSize:指定了线程池中的核心线程数量。
  2. maximumPoolSize:指定了线程池中的最大线程数量。
  3. keepAliveTime:当前线程池数量超过 corePoolSize 时,多余的空闲线程的存活时间,即多
  4. 次时间内会被销毁。
  5. unit:keepAliveTime 的单位。
  6. workQueue:任务队列,被提交但尚未被执行的任务。
  7. threadFactory:线程工厂,用于创建线程,一般用默认的即可。
  8. handler:拒绝策略,当任务太多来不及处理,如何拒绝任务。

二、常见的四种线程池

1、newCachedThreadPool

创建一个可根据需要创建新线程的线程池,但是在以前构造的线程可用时将重用它们。对于执行很多短期异步任务的程序而言,这些线程池通常可提高程序性能。调用 execute 将重用以前构造的线程(如果线程可用)。如果现有线程没有可用的,则创建一个新线程并添加到池中。终止并从缓存中移除那些已有 60 秒钟未被使用的线程。因此,长时间保持空闲的线程池不会使用任何资源。
 
适合于耗时短,不需要考虑同步的场合;
 

2、newFixedThreadPool

创建一个可重用固定线程数的线程池,以共享的无界队列方式来运行这些线程。在任意点,在大多数 nThreads 线程会处于处理任务的活动状态。如果在所有线程处于活动状态时提交附加任务,则在有可用线程之前,附加任务将在队列中等待。如果在关闭前的执行期间由于失败而导致任何线程终止,那么一个新线程将代替它执行后续的任务(如果需要)。在某个线程被显式地关闭之前,池中的线程将一直存在。
 
符合常用场合;
 

3、newScheduledThreadPool

创建一个线程池,它可安排在给定延迟后运行命令或者定期地执行;
ScheduledExecutorService scheduledThreadPool= Executors.newScheduledThreadPool(3);
scheduledThreadPool.schedule(newRunnable(){
    @Override
    public void run() {
        System.out.println("延迟三秒");
    }
}, 3, TimeUnit.SECONDS);

scheduledThreadPool.scheduleAtFixedRate(newRunnable(){
    @Override
    public void run() {
        System.out.println("延迟 1 秒后每三秒执行一次");
    }
},1,3,TimeUnit.SECONDS);
适合定时以及周期性执行任务的场合;
 

4、newSingleThreadExecutor

Executors.newSingleThreadExecutor()返回一个线程池(这个线程池只有一个线程),这个线程池可以在线程死后(或发生异常时)重新启动一个线程来替代原来的线程继续执行下去!
 
适合于需要保证执行顺序的场合;

 

三、线程池的拒绝策略

AbortPolicy(终止策略、默认策略)
线程池队列满的时候,丢弃任务并抛出RejectedExecutionException异常,直接抛出异常,阻止系统正常运行
DiscardPolicy(抛弃策略)
线程池队列满的时候,丢弃任务,但是不抛出异常。
DiscardOldestPolicy(抛弃旧任务策略)
将最早进入队列的任务删,也就是即将被执行的一个任务,并尝试再次提交当前任务。
CallerRunsPolicy(调用者运行策略)
 如果添加到线程池失败,那么主线程会自己去执行该任务(这个时候会严重影响程序效率)
自定义
继承RejectedExecutionException类

 

posted on 2021-03-31 22:35  中都  阅读(71)  评论(0)    收藏  举报
Live2D