Java 线程池

2020-05-19  本文已影响0人  攻城狮托马斯

什么是线程池, 为什么要用线程池


线程池是最常见的并发框架, 好处是:

原来线程需要 T1:创建 T2:运行 T3:销毁, 有了线程池以后, 可以直接让另一个线程运行. 这么做的好处则是

1.降低资源消耗,不需要再去创建其他新的线程了.

2.提高响应速度, 不需要在T1和T3步骤上花时间.

3.提高线程可管理性,

线程池的实现


Executer接口框架

接口——>抽象类——>实现类

(上课一笔带过,具体不考)

面试必考


threadPool 初始化.

各个参数含义:

CorePoolSize():线程的数量
MaximumPoolSize():最大线程数量

KeepAliveTime 线程空闲的存活时间

TimeUnit Unit:线程空闲存活时间的单位

BlockingQueue<Runnable> workQueue(): 阻塞队列
1.传入一个任务, 新建一个线程,直到达到CorePoolSize()

2.当达到CorePoolSiz()的时候, 传入到阻塞队列

3.当阻塞队列满的时候,创建线程, 但不能超过MaximumPoolSize().

4.如果超过了MaximumPoolSize(), 则调用RejectionExecutionHandler(接口), 其中有四个实现方法:

a.删掉最老的等待线程

b.抛出异常

c.提交任务者执行任务(主线程提交任务, 主线程去执行)

d.自定义执行任务,比如可以把任务扔到数据库里面去。

线程池中的线程工厂(Executer.defaultThreadFactory, ThreadFactory也是接口)

重要用于给线程命名,比如说pool+序列号+thread, 并且会把所有的线程设置为守护线程,当主线程退出的时候,守护线程不论如何都会退出。如果不设置成守护线程的话,那要等每一个线程都退出才能退出,没有办法强制关闭.

如果想要在线程开始和结束打印话,则可以使用beforeExecutor和AfterExecutor来打印, 是两个没有实现的方法, 以及terminated(), 在线程池结束后的方法.

如果传入的是callable()实现的线程, 那么如下, 可以开一个future并通过submit函数来实现返回值.

Execute(提交没有返回值的任务), submit(提交有返回值的任务)

线程池的关闭


shutDown() && shutDownNow()

shutDown(): 遍历每一个线程,Call一遍Interrupt, 改了Interrupt的标志位.

ShutDownNow(): 强行中断,任务不一定执行完.

如何合理配置线程池


合理配置线程池需要知道任务的特性:

1.CPU密集型, 不断从内存中获取数据  2.IO密集型, 总是和磁盘与网络 3.混合型

CPU密集型: 配置线程数不超过当前机器上的CPU数

IO密集型:经验取值, CPU数X2(如果CPU还是很闲, X3或X4)

混合型: 拆分成两个线程池, 如果两个任务时间相差不大的话(如果大的话, 则不用拆分,因为没有太大改善)

BlockingQueue<>的选择


BlockingQueue一定要是有界队列,如果是无界的话,就会无线扩充,一旦OOM导致的话有可能导致线程池停止。

上一篇下一篇

猜你喜欢

热点阅读