【学习笔记-并发编程实战】第8章 线程池的使用

在任务与执行策略之间的隐形耦合

不是所有的任务都适合直接将其甩给线程池进行执行,然后可以随意的更改线程池的配置,只影响效率,而不影响其他。如以下任务:

依赖性任务

任务并不是完全独立的,而是要依赖其他任务的执行结果

使用线程封闭机制的任务

任务只能在单线的线程池中运行,从而保证任务的线程安全

对响应时间敏感的任务

将一个长时间任务甩给一个线程数量不多的线程池,将会导致某些任务长时间等待,如果是gui程序,将严重影响其响应时间

使用ThreadLocal的任务

使用ThreadLocal来封闭线程的变量副本确保变量的线程安全

线程饥饿死锁

一个任务A提交另外一个任务B到同样的Executor中,如果线程池数量不够大,则有可能形成A等待B执行完成,而B在等待A执行完成,从而形成饥饿死锁。

运行时间较长的任务

当线程池中所有任务都去执行运行时间较长的任务时,从而影响整体的性能。

 

设置线程池大小

对于计算密集性任务,当线程池大小为Ncpu+1时,通常能实现最优利用率。对于包含IO密集型的任务,还可以将线程池的规模扩展至更大。

 

配置ThreadPoolExecutor

线程池的创建与销毁

通过线程池的参数 corePoolSize(基本大小),maximumPoolSize(最大大小)、keepAliveTime(空闲存活时间)属性来确定线程池。当线程队里满了之后,会产生超出线程池基本大小的线程。

管理队列任务

newFixedThreadPool和newSingleThreadPool使用LinkedBlockingQueue的无界队列。newCachedThreadPool使用一种假队列,直接将任务移交给线程。

饱和策略

中止:抛异常

抛弃:悄悄抛弃任务

抛弃最旧的:抛弃旧任务

调用者运行:将任务退回给调用线程,让调用线程的主线程执行任务,如果任务量过大,则一路阻塞,从线程池到工作队列到应用程序再到TCP层,最终到达客户端,从而实现性能的平滑下降。

线程工厂

 

在调用构造函数后再定制ThreadPoolExecutor

见名知意,其他的暂时没有什么好说的。

 

扩展ThreadPoolExecutor

通过继承ThreadPoolExecutor线程池,重写beforeExecutor、afterExecutor、terminated方法,来增强线程池实现自己的线程池功能。

 

递归算法的并行化

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值