java线程池的使用

1、在任务与执行策略之间的隐性耦合

虽然Executor框架为制定和修改执行策略都提供了相当大的灵活性,但并非所有的任务都能适用所有的执行策略。有些类型的任务需要明确地指定执行策略,包括:1:依赖性任务;2:适用线程封闭机制的任务;3.对响应时间敏感的任务;4:适用ThreadLocal的任务;

(1)每次提交了一个有依赖性的Executor任务时,要清楚地知道可能会出现线程”饥饿:死锁,因此需要在代码或配置Executor的配置文件中记录线程池的大小限制与配置限制。

(2)运行时间较长的任务

限定任务等待资源的时间,可以缓解执行时间较长任务造成的影响。

在平台类库的大多数可阻塞方法中,都同时定义了显示版本和无限时版本。

例如:Thread.join、BlockingQueue.put、CountDownLatch.await以及Selector.select等


2、设置线程池的大小

线程池的理想大小取决于被提交任务的类型以及所部属系统的特性。在代码中,通常不会固定线程池的大小,而应该通过某种配置机制来提供,或者根据Runtime.availableProcessors来动态计算。

计算密集型的任务,在拥有N(cpu)个处理器的系统上,当线程池的大小为n+1时,通常能实现最优的利用率;

I/O密集型,由于线程并不会一直在执行,估算任务等待的时间与计算时间的比值;

U(cpu)=cpu的利用率,0=<U<=1; w/c = 计算机计算等待的时间/计算时间

线程池的最优大小:N(thread) = N(cpu)*U(cpu的效益)*(1+w/c)

注:影响线程池大小资源,还包括内存、文件句柄、套结子句柄和数据库连接等;


3、配置ThreadPoolExecutor

(1)线程的创建与销毁

线程池的基本大小、最大大小以及存活时间等因素共同负责线程的创建与销毁。

(2)管理队列任务

基本任务队列有3种:无界队列、有界队列和同步移交

无界队列:当任务超过了线程池处理它们的速度,那么队列将无线增加;

有界队列:就是队列的容量有限;

同步移交:避免任务排队,直接将任务从生产者移交给消费者;

(3)饱和策略

当有界队列被填满后,饱和策略开始发挥作用。ThreadPoolExecutor可以通过调用setrejectedExecutionHandler来修改;

RejectedExecutionHandler实现:AbortPolicy(默认),callerRunsPolicy,DiscardPolicy和DiscardOldestPolicy。

(4)线程工厂

每当线程池需要创建一个线程时,都是通过线程工厂方法来完成的。ThreadFactory接口中定义了一个方法:newThread();

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

在调用玩ThreadPoolExecutor的构造函数后,仍然可以通过设置函数(setter)来修改大多数传递给它的构造函数的参数;


4、扩展ThreadPoolExecutor

ThreadPoolExecutor是可扩展的,它提供了几个可以在子类化中改写的方法:beforeExecute、afterExecute和terminated,用于扩展ThreadPoolExecutor的行为。在这些方法中,可以添加日志、计时、监视或统计信息收集的功能。

     在线程池完成关闭操作时调用terminated,可以用来释放Executor在其生命周期里分配的各种资源。此外,还可以执行发送通知、记录日志或者收集finalize统计信息等操作。


5、递归算法的并行化

当串行循环中的各个迭代操作彼此独立时,并行每个迭代操作执行的工作亮比管理一个新任务带来的开销更多,那么这个串行循环就适合并行化。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值