为什么使用线程池?线程池的作用是什么?线程池的执行顺序?线程池的入参是哪些?分别代表什么意思?
频繁的创建线程与销毁线程,资源耗费与上下文切换时间开销非常大,而线程池可以避免这种情况.
入参有核心线程数,最大线程数,等待队列,过期时间,等待策略,时间单位,线程工厂(不重要)一般用默认的.
当有任务的时候,线程池会不断创建核心线程数直到设置的数量,如果还是有任务,就会加入到等待队列当中去;当等待队列满了,就会开启最大线程数线程的创建。
如果最大线程也满了,就会执行拒绝策略。根据拒绝策略的设置,如默认的是AbortPolicy丢弃任务并抛出异常。
当任务少了,最大线程数空闲了就会减少,只剩下核心线程数而这时间就是过期时间
其中核心线程数如果没满,即使有的线程在空转也会新建线程。
队列:
否则一直阻塞
阻塞队列
ArrayBlockingQueue:一个由数组结构组成的有界阻塞队列。
LinkedBlockingQueue:一个由链表结构组成的有界阻塞队列。
PriorityBlockingQueue:一个支持优先级排序的无界阻塞队列。
DelayQueue:一个使用优先级队列实现的延迟无界阻塞队列。
SynchronousQueue:一个不存储元素的阻塞队列。
LinkedTransferQueue:一个由链表结构组成的无界阻塞队列。
LinkedBlockingDeque:一个由链表结构组成的双向阻塞队列。
拒绝策略:默认的是AbortPolicy
有界队列和无界队列的使用区别?
无界队列,因为不会跑最大线程数,所以也不会有拒绝策略
使用场景是:
线程池的种类:
重要的1四中
线程提交任务的两种方式,区别是什么?
方式一:调用execute()方法
方式二:调用submit()方法
1.二者所接收的参数不一样
Execute()方法只能接收Runnable类型的参数,而submit()方法可以接收Callable、Runnable两种类型的参数。Callable类型的任务是可以返回执行结果的,而Runnable类型的任务不可以返回执行结果。Callable是JDK 1.5加入的执行目标接口,作为Runnable的一种补充,允许有返回值,允许抛出异常。Runnable和Callable的主要区别为:Callable允许有返回值,Runnable不允许有返回值;Runnable不允许抛出异常,Callable允许抛出异常。
2.submit()提交任务后会有返回值,而execute()没有
execute()方法主要用于启动任务的执行,而任务的执行结果和可能的异常调用者并不关心。submit()方法也用于启动任务的执行,但是启动之后会返回Future对象,代表一个异步执行实例,可以通过该异步执行实例去获取结果。
3.submit()方便Exception处理
execute()方法在启动任务执行后,任务执行过程中可能发生的异常调用者并不关心。而通过submit()方法返回的Future对象(异步执行实例),可以进行异步执行过程中的异常捕获。