必必须掌握的线程池知识点

线程池是一个典型的“用空间换时间”的应用案例,在线程池中始终维护一定数量的线程,这样不必每次都创建新的线程,代价是线程即使空闲的时候也要占用内存资源。

当需要频繁创建和销毁线程的时候,使用线程池可以显著提高系统的运行效率,在线程池的不同种类中,缓存线程池在通常情况下都是性能最好的。

 

知识点一、线程池的好处

1.可以重用线程池中的线程,避免应用中频繁的创建和销毁线程所造成的内存消耗以及性能上不必要的开销

2.通过控制线程池的最大线程数能有效控制线程池的最大并发数,避免大量的线程同一时间并发抢占系统资源而造成的阻塞和界面卡死

3.可以自己管理线程,定时执行,间隔循环执行,线程关闭等,通过对线程的管理可以避免滥用多线程造成的问题,比如内存泄露、界面卡死、CPU阻塞等


知识点二、Runnable和Callable的区别

在提交任务到线程池的时候,通常实现Runnable接口的使用execute()方法提交,实现Callable接口的使用submit()方法提交。最后,使用线程池后别忘了shutdown()

(1)Callable规定的方法是call(),Runnable规定的方法是run()

(2)Callable的任务执行后可返回值,而Runnable的不能返回值

(3)call方法可以抛出异常,run方法不可以

(4)运行Callable任务可以拿到一个Future对象,表示异步计算的结果,它提供了检查计算是否完成的方法,以等待计算的完成,并检索计算的结果。通过Future对象可以了解任务执行情况,可取消任务的执行,还可获取执行结果

 

知识点三、使用Executor框架创建线程池

Executor框架最核心的类是ThreadPoolExecutor,线程池都是通过对ThreadPoolExecutor进行不同配置来实现的

ThreadPoolExecutor有四个重载的构造方法,参数最多的那一个重载的构造方法,有7个参数

1.corePoolSize 线程池中核心线程的数量

2.maximumPoolSize 线程池中最大线程数量

3.keepAliveTime 非核心线程的超时时长,当系统中非核心线程闲置时间超过keepAliveTime之后,则会被回收。如果ThreadPoolExecutor的allowCoreThreadTimeOut属性设置为true,则该参数也表示核心线程的超时时长

4.unit 第三个参数的单位,有纳秒、微秒、毫秒、秒、分、时、天等

5.workQueue 线程池中的任务队列,该队列主要用来存储已经被提交但是尚未执行的任务。存储在这里的任务是由ThreadPoolExecutor的execute方法提交来的

6.threadFactory 为线程池提供创建新线程的功能

7.handler 拒绝策略

Executor可以创建三个比较常见的线程池(线程池的种类)

FixedThreadPool,创建固定长度的线程池,每次提交任务创建一个线程,直到达到线程池的最大数量,线程池的大小不再变化,固定数量一次支付之后使用不再开销

SingleThreadExecutor,线程池中只有一个线程,所有任务按照添加顺序执行,任务之间不会相互干扰,结果更准确

CachedThreadPooll是一个”无限“容量的线程池,和缓存有关的线程池,如果池中没有空闲的线程,线程池就会为这个任务创建一个线程,如果有空闲的线程,就会使用已有的空闲线程执行任务,CachedThreadPool是一个比较通用的线程池,它在多数情况下都能表现出优良的性能。遇事不决,用缓存线程池

 

知识点四、线程池执行策略

1.execute(执行)一个线程之后,如果线程池中的线程数未达到核心线程数,则会立马启用一个核心线程去执行

2.execute一个线程之后,如果线程池中的线程数已经达到核心线程数,且workQueue未满,则将新线程放入workQueue中等待执行

3.execute一个线程之后,如果线程池中的线程数已经达到核心线程数但未超过非核心线程数,且workQueue已满,则开启一个非核心线程来执行任务

4.execute一个线程之后,如果线程池中的线程数已经超过非核心线程数,则拒绝执行该任务

 

 

你可能感兴趣的:(线程)