Java线程池

什么是线程池?

线程池是一种多线程处理方式,处理任务的过程中将任务交给线程池来管理。

为什么要使用线程池?

创建线程和销毁线程的花销是比较大的,这些时间有可能比处理业务的时间还要长。如果每执行一条任务都要创建一个线程的话,服务器的资源很快就会耗尽,使用线程池可以减少线程创建和销毁的次数,每个工作线程都可以被重复利用,可以执行多个任务。

线程池有什么作用?

1.提高效率,创建好一定数量的线程放入线程池里,当有任务需要执行时就从线程池中拿出一个工作线程去执行任务,比需要时才创建线程的效率要快。

2.方便管理,可以修改线程池参数对线程池中的线程进行管理,比如说启动时有该程序创建100个线程,每当有请求的时候,就分配一个线程去工作,如果刚好并发有101个请求,那多出的这一个请求可以排队等候,避免因无休止的创建线程导致系统崩溃。

线程池的重要参数

1.corePoolSize:线程池中的核心线程的数量,该线程在没有使用的情况下也不会被回收。

2.maximumPoolSize:线程池中可以容纳最多的线程数量

3.keepAliveTime:线程中(除核心线程之外的线程)的最长保留时间,如果非核心线程在最长保留时间之内还没有获取到任务的话,会被回收。

4.util:计算时间的单位,时分秒。

5.workQueue:等待队列,任务可以存储在任务队列中等待被执行(执行原则:先进先出)。

6.threadFactory:创建线程的线程工厂

7.handler:一种拒绝策略

拒绝策略

当请求任务不断的过来,而系统此时又处理不过来的时候,我们需要采取的策略是拒绝服务。

RejectedExecutionHandler接口提供了拒绝任务处理的自定义方法的机会。在ThreadPoolExecutor中已经包含四种处理策略。

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

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

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

4.DiscardPolicy策略:该策略默默的丢弃无法处理的任务,不予任何处理。

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

execute和submit的区别?

(1)可以接受的任务类型
execute只能接受Runnable类型的任务
submit不管是Runnable还是Callable类型的任务都可以接受

(2)返回值
execute没有返回值
submit有返回值,所以需要返回值的时候必须使用submit

(3)异常
1.execute中抛出异常
execute中的是Runnable接口的实现,所以只能使用try、catch来捕获CheckedException,通过实现UncaughtExceptionHande接口处理UncheckedException
即和普通线程的处理方式完全一致

2.submit中抛出异常
不管提交的是Runnable还是Callable类型的任务,如果不对返回值Future调用get()方法,都会吃掉异常

五种线程池的使用场景

1.newSingleThreadExecutor:一个单线程的线程池,可以用于需要保证顺序执行的场景,并且只有一个线程在执行。

2.newFixedThreadPool:一个固定大小的线程池,可以用于已知并发压力的情况下,对线程数做限制。

3.newCachedThreadPool:一个可以无限扩大的线程池,比较适合处理执行时间比较小的任务。

4.newScheduledThreadPool:可以延时启动,定时启动的线程池,适用于需要多个后台线程执行周期任务的场景。

5.newWorkStealingPool:一个拥有多个任务队列的线程池,可以减少连接数,创建当前可用cpu数量的线程来并行执行。

线程池的关闭

shutdownNow:对正在执行的任务全部发出interrupt(),停止执行,对还未开始的任务全部取消,并且返回还没开始的任务列表

shutdown:当我们调用shutdown后,线程池将不再接受新的任务,但不回去强制终止正在执行或已经提交的任务。

线程池都有哪几种工作队列

1、ArrayBlockingQueue

是一个基于数组结构的有界阻塞队列,此队列按 FIFO(先进先出)原则对元素进行排序。

2、LinkedBlockingQueue

一个基于链表结构的阻塞队列,此队列按FIFO (先进先出) 排序元素,吞吐量通常要高于ArrayBlockingQueue。静态工厂方法Executors.newFixedThreadPool()使用了这个队列

3、SynchronousQueue

一个不存储元素的阻塞队列。每个插入操作必须等到另一个线程调用移除操作,否则插入操作一直处于阻塞状态,吞吐量通常要高于LinkedBlockingQueue,静态工厂方法Executors.newCachedThreadPool使用了这个队列。

4、PriorityBlockingQueue

一个具有优先级的无限阻塞队列。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值