java线程池学习

java线程池

java线程池

为什么需要java线程池

​ 在java开发中,并发是一个很常见的问题,所谓并发就是多个线程同时执行,但是实际上只有一个cpu核数在执行,CPU通过任务切换,可以使几个线程在一定时间内执行完成,而由于执行速度快,所以给人的感觉好像是几个任务同时执行。在java里面有专门的线程类,但是在实际开发中我们并不直接使用这个类去创建对象,而是使用线程池来处理我们的任务,其好处是使用池化技术可以专门对线程进行管理,实现线程的管理和复用,从而减少资源消耗。

image-20201026215525882

线程池的核心参数和核心类

线程池的核心类为ThreadPoolExecutor,其核心参数如下:

corePoolSize :核心线程数。

maximumPoolSize:最大线程数。

keepAliveTime:空闲的线程保留的时间(新创建的临时线程)。

TimeUnit:空闲线程的保留时间单位。

BlockingQueue:阻塞队列,读取时为空或者写入时满了将会一直被阻塞等待。

ThreadFactory:线程工厂,用来创建线程。

RejectedExecutionHandler:异常处理策略。

常用的阻塞队列

LinkedBlockingQueue:基于链表的阻塞队列。

ArrayBlockingQueue:基于数组的阻塞队列。

SynchronousQueue:异步阻塞队列,只能存取一个任务。

常见的四种任务拒绝策略

AbortPolicy:丢弃任务并抛出RejectedExecutionException异常.

DiscardPolicy:弃任务,但是不抛出异常。如果线程队列已满,则后续提交的任务都会被丢弃,且是静默丢弃。

DiscardOldestPolicy:丢弃队列最前面的任务,然后重新提交被拒绝的任务。

CallerRunsPolicy:返回给调用线程(提交任务的线程)执行此任务。

线程池运行流程

​ 创建好线程池后,默认没有线程创建,当提交任务后,才会创建线程去处理,当任务数超过核心线程数时,会把后面的任务放到阻塞队列,如果阻塞队列满了,便会创建新的线程再去处理,一旦总的线程数量达到了最大线程数量,那么后面的任务将会采取任务任务拒绝策略处理。

image-20201026223227975

创建线程池的方式

使用Executors工具类创建线程池

1、newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。

2、newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。

3、newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。(不常用)

4、newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。

​ 虽然Executors可以创建多种线程池,但是在实际开发并不这样使用,因为Executors大部分都使用了LinkedBlockingQueue,而LinkedBlockingQueue能够容纳的任务数是2亿多,相当于无界队列,因为Executors也是使用的ThreadPoolExecutor这个类创建线程的,所以我们应该使用ThreadPoolExecutor类来创建线程池。

public class TestExecutor {
    
    public static void main(String[] args) {
        
        //ExecutorService executor = Executors.newFixedThreadPool(3);
        ExecutorService executor = new ThreadPoolExecutor(1,
                6,
                1L,
                TimeUnit.SECONDS,
                new LinkedBlockingQueue<Runnable>(3),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.DiscardPolicy());

        try {
            for (int i = 0; i <20 ; i++) {

                executor.execute(()->{
                    System.out.println(Thread.currentThread().getName()+"执行任务");
                });

            }

        }catch (Exception e){
            e.printStackTrace();

        }finally {
            executor.shutdown();
        }

    }
}

ThreadPoolExecutor类的线程数配置

image-20201026223406974

image-20201026223425690

image-20201026223451934

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值