Java线程池

一、什么是线程池

        简单来说就是一个存放线程的容器,可以容纳多个线程,其中的线程可以反复使用。

二、为什么要创建线程池

        线程的创建和销毁都是很耗费资源的,创建线程池之后可以减少这种消耗。同时,如果在一个jvm里创建了太多线程,也会导致系统内存被过度消耗,“切换过度”会造成系统资源不足,而线程池可以对线程的数量加以限制,也能很好的解决这个问题。

三、Executor与ExecutorService的区别

ExecutorExecutorService
是Java线程池的核心接口,用来并发执行提交提交的任务ExecutorService是Executor接口的扩展,提供了异步执行和关闭线程池的方法
execute()方法用来提交任务,没有返回值使用submit()来提交任务,返回Future对象,可以获取任务执行结果
不能取消任务可以用Future.cancel()取消pending中的任务
没有关闭线程池的方法提供了关闭线程池的方法

 四、Executors

        提供工厂方法来创建不同类型的线程池,下面是它所提供的四种线程池:

        (1)newCachedThreadPool:线程池根据需求创建线程,可扩容。

        特点:1.线程池数量不固定,可达到最大值

                   2.线程池中的线程可以进行缓存重复利用和回收(回收的时间默认一分钟)

                   3.当线程池中没有可用线程,会重新创建一个线程

       适用于创建一个可无限扩大的线程池,服务器负载压力比较轻,执行时间较短,任务多的场景

        (2)newSingleThreadExecutor:一个任务一个任务执行,一池一线程

                特点:线程中最多执行1个线程,之后提交的线程活动将会排在队列中等待执行,提交顺序就是执行顺序

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

        (3)newFixedThreadPool(int):一池N线程

                特点:1.线程池中的线程处于一定的量,可以很好的控制线程的并发量

                           2.线程可以重复使用,在显示关闭之前,都将一直存在

                           3.超出量的线程被提交的时候需在队列中等待

                使用于可以预测线程数量的业务中,或者服务器负载比较重,对线程有严格限制的场景

          (4)newScheduledThreadPool (了解)

                   创建一个大小无限的线程池,此线程池支持定时以及周期性执行任务的需求。

                   场景: 适用于需要多个后台线程执行周期任务的场景

都是通过new ThreadPoolExecutor来构造线程池,线程池相关参数:

  1.  corePoolSize:核心线程数量(常驻线程),一般情况下不管有没有任务都会在线程池中一直存活
  2.  maximumPoolSize:线程池所能容纳的最大线程数,当活动的线程数达到这个值后,后续的新任务将被阻塞
  3.  keepAliveTime:线程闲置超时的时长,当线程的闲置时长超过这个数后,会被终止,一般用于非核心线程
  4. unit:时间单位,用于指定keepAliveTime参数的时间单位
  5. workQueue:任务队列(阻塞队列),当线程数超过核心线程数时,新任务会放到阻塞队列中等待执行
  6. threadFactory:线程工厂,是一个接口,用来为线程池创建新线程
  7. RejectedExecutionHandler:拒绝策略

 

拒绝策略:

  • AbortPolicy(默认):直接抛出RejectedExecutionException异常组织系统正常运行
  • CallerRunsPolicy:“调用者运行”一种调节机制,该策略既不会抛弃任务,也不会抛出异常,而是将某些任务退回到调用者,降低新任务的流量
  • DiscardOldestPolicy:摒弃队列中等待最久的任务,把新的任务加入到队列中,尝试再次提交当前任务
  • DiscardPolicy:默默丢弃无法处理的任务,不做处理也不抛出异常。如果任务允许丢失,这将是最好的一种策略。

五、线程池的关闭

        ThreadPoolExecutor 提供了两个方法,用于线程池的关闭,分别是 shutdown() 和shutdownNow()。

shutdown():不会立即的终止线程池,而是要等所有任务缓存队列中的任务都执行完后才终止,但再也不会接受新的任务。

shutdownNow():立即终止线程池,并尝试打断正在执行的任务,并且清空任务缓存队列,返回尚未执行的任务。

六、代码实现

public class ThreadPoolDemo {

    public static void main(String[] args) {
        // 一池5线程
        // ExecutorService threadPool = Executors.newFixedThreadPool(5);
        // 一池一线程
        // ExecutorService threadPool = Executors.newSingleThreadExecutor();
        // 一池可扩容线程
        // ExecutorService threadPool = Executors.newCachedThreadPool();

        ExecutorService threadPool = new ThreadPoolExecutor(
                2,
                5,
                2L,
                TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(3),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy()
        );

        for (int i = 1; i <=10; i++) {
            final int index = i;
            threadPool.execute(new Runnable() {
                @Override
                public void run() {
                    System.out.println(Thread.currentThread().getName() + "为第"+index+"个任务服务");
                }
            });
        }

        threadPool.shutdown();
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值