Executors线程池

        //工作中只用这种
        //最大线程数定义 1.CPU密集型 几核就是几 可保证CPU效率最高
        Runtime.getRuntime().availableProcessors();//获取CPU核数
        //IO密集型 判断程序中十分消耗IO资源线程大于这个数
//        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2,//核心线程数
        ExecutorService threadPoolExecutor = new ThreadPoolExecutor(2,//核心线程数
                5,//最大线程数
                1,//超时时间
                TimeUnit.SECONDS,//单位秒
                new LinkedBlockingQueue<>(3),//任务队列,设置队列大小
                Executors.defaultThreadFactory(),//线程工厂,默认线程工厂
                new ThreadPoolExecutor.AbortPolicy());//拒绝策略

定长线程池(FixedThreadPool) 

//特点:只有核心线程,线程数量固定,执行完立即回收。
//任务队列为链表结构的有界队列:LinkedBlockingQueue
//一个基于链表结构的阻塞队列,此队列按FIFO (先进先出)排序元素,
//吞吐量通常要高于ArrayBlockingQueue。静态工厂方法Executors.newFixedThreadPool()使用了这个队列
//应用场景:一个固定大小的线程池,可以用于已知并发压力的情况下,对线程数做限制,控制线程最大并发数。
   ExecutorService executorService = Executors.newFixedThreadPool(5);
         try {
           //最大承载为队列+最大线程数
            for (int i = 0; i < 10; i++) {
                //使用线程池创建线程
                scheduledExecutorService.execute(() -> {
                    System.out.println(Thread.currentThread().getName());
                });
            }
        }finally {
            //线程池用完要关闭
            scheduledExecutorService.shutdown();
        }

 单线程化线程池(SingleThreadExecutor) 

//特点:只有 1 个核心线程,无非核心线程,执行完立即回收。
// 任务队列为链表结构的有界队列:LinkedBlockingQueue
// 一个基于链表结构的阻塞队列,此队列按FIFO (先进先出)排序元素吞吐量通常要高于ArrayBlockingQueue。
// 静态工厂方法Executors.newFixedThreadPool()使用了这个队列
// 应用场景:一个单线程的线程池,可以用于需要保证顺序执行的场景,并且只有一个线程在执行。
// 不适合并发但可能引起 IO 阻塞性及影响 UI 线程响应的操作,如数据库操作、文件操作等。
 ExecutorService executorService = Executors.newSingleThreadExecutor();

可缓存线程池(CachedThreadPool) 

//特点:无核心线程,非核心线程数量无限,执行完闲置 60s 后回收。
//任务队列为不存储元素的阻塞队列:SynchronousQueue
//一个不存储元素的阻塞队列。每个插入操作必须等到另一个线程调用移除操作,
// 否则插入操作一直处于阻塞状态,吞吐量通常要高于LinkedBlockingQueue,
// 静态工厂方法Executors.newCachedThreadPool使用了这个队列。
// 应用场景:执行大量、耗时少的任务。一个可以无限扩大的线程池,比较适合处理执行时间比较小的任务。
         ExecutorService executorService = Executors.newCachedThreadPool();

//定时线程池(ScheduledThreadPool ) 

//特点:核心线程数量固定,非核心线程数量无限,执行完闲置 10ms 后回收。
//任务队列为延时阻塞队列:DealyQueue
//应用场景:执行定时或周期性的任务。定时启动的线程池,适用于需要多个后台线程执行周期任务的场景。
    ScheduledExecutorService scheduledExecutorService =Executors.newScheduledThreadPool(5);

线程池的核心参数:

corePoolSize(必需):核心线程数。默认情况下,核心线程会一直存活,但是当将 allowCoreThreadTimeout 设置为 true 时,核心线程也会超时回收。

maximumPoolSize(必需):线程池所能容纳的最大线程数。当活跃线程数达到该数值后,后续的新任务将会阻塞。

keepAliveTime(必需):线程闲置超时时长。如果超过该时长,非核心线程就会被回收。如果将 allowCoreThreadTimeout 设置为 true 时,核心线程也会超时回收。

unit(必需):指定 keepAliveTime 参数的时间单位。常用的有:TimeUnit.MILLISECONDS(毫秒)、TimeUnit.SECONDS(秒)、TimeUnit.MINUTES(分)。

workQueue(必需):任务队列。通过线程池的 execute() 方法提交的 Runnable 对象将存储在该参数中。其采用阻塞队列实现。

threadFactory(可选):线程工厂。用于指定为线程池创建新线程的方式。(一般不用动)

handler(可选):拒绝策略。当达到最大线程数时需要执行的饱和策略。

线程池的拒绝策略:

 当请求任务不断的过来,而系统此时又处理不过来的时候,我们需要采取的策略是拒绝服务。RejectedExecutionHandler接口提供了拒绝任务处理的自定义方法的机会。在ThreadPoolExecutor中已经包含四种处理策略。

AbortPolicy(中止策略)策略:该策略会直接抛出异常,阻止系统正常工作。

CallerRunsPolicy 策略:只要线程池未关闭,该策略直接在调用者线程中,运行当前的被丢弃的任务。

DiscardOleddestPolicy策略: 该策略将丢弃最老的一个请求,也就是即将被执行的任务,并尝试再次提交当前任务。

DiscardPolicy策略:忽略新任务;不予任何处理。

    除了JDK默认提供的四种拒绝策略,我们可以根据自己的业务需求去自定义拒绝策略,自定义的方式很简单,直接实现RejectedExecutionHandler接口即可。

execute和submit的区别:

线程池执行任务是用的execute方法,除了execute方法,还有一个submit方法也可以执行我们提交的任务。

这两个方法有什么区别呢?分别适用于在什么场景下呢?

execute适用于不需要关注返回值的场景,只需要将线程丢到线程池中去执行就可以了。

submit方法适用于需要关注返回值的场景

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值