码迷,mamicode.com
首页 > 编程语言 > 详细

java并发的艺术-读书笔记-第九章线程池

时间:2017-09-14 10:36:23      阅读:163      评论:0      收藏:0      [点我收藏+]

标签:java 线程池原理

使用线程池的好处:

1.降低资源消耗:减少了线程创建和销毁的资源消耗

2.提高响应速度,当任务到达时,线程可以不尽兴创建直接处理

3.提高线程的可管理性。使用线程池可以对线程进行统一的管理,监控,使用。

线程池的源码分析:

public void execute(Runnable command){

if(command==null){

throw new NullPointerException();

}

//如果执行线程数小于基本线程,则创建线程,并执行任务

if(poolsize>=corepoolsize||!addifundercoresize(command)){

//如果线程池数量大于等于核心池数量或者线程创建失败,直接放入队列中

if(runstate==runnable&&workQueue.offer(command)){

if(runstate!=runnable||poolsize==0){

eusureQueueTaskHandled(command);

}

}

//如果线程池不处于运行中或者无法放入任务队列,并且当前线程小于最大允许线程,则创建新线程

if(!addundermaxpoolsize(command)){

reject(command);

}

}

}

工作线程伪代码如下:

public void runnable(){

Runnable task=firsttask;

firsttask=null;

while(task!=null||task=workQueue.get()!=null){

runtask(task);

task=null;

}

finally{

workDone(this);

}

}

线程池的使用

创建线程池:new ThreadPoolExecutor(corepoolsize,maxpoolsize,keepalivetime,millseconds,runnabletaskqueue,hander);

参数说明

runnabletaskqueue,是一个用于存储任务的阻塞队列,通常 arryayblockingqueue linkedblockingqueue pritoryblockingqueue

hander:饱和策略:1 abortpolicy  丢弃  2 discardpolicy  不丢弃 3 callerrunspolicy 只有调用者线程来执行,discardoldestpolicy 丢弃队列里最近的一个任务,并执行当前任务

keepalivetime:线程池中的工作线程空闲后,可以保持存活的有效时间

timeunit:可保持存活时间的 有效单位 天 ,小时 分,秒等

向线程池中提交任务:execute 和submit

execute 用于提交无返回值的结果

submit用于提交有返回值的线程

通过submit方法提交的线程会返回一个future类型的对象,通过这个future类对象可以判断返回值时否成功。通过future。get方法获取返回值,get方法会阻塞当前线程,直到任务完成,并且get方法可以设置时间来实现异步调用返回

关闭线程池

关闭线程池游两种方法:shutdown shutdownNow方法关闭线程池

shutdown原理:逐个遍历工作线程,调用工作线程的interrupt方法,所以无法中断响应的线程可能无法终止。

shutdownnow原理:首先将线程池设置成stop状态,然后尝试终止所有正在执行或暂停任务的线程,并返回等待执行的任务列表。只要调用了两种方法中的任意一种,则isshutdown返回true,当所有任务已关闭,才表示线程池关闭成功则isterminaled返回true,shutdownnow方法可能任务不一定会执行完。通常使用shutdown来关闭

合理配置线程池

cpu密集型任务应配置尽可能小的线程。如配置cup+1个线程。由于io密集型任务并不一定是在一直执行任务。所以应配置尽可能多的线程,如配置2*cup个线程。如果是混合型的任务则可以拆分。拆分成一个cup密集型的任务和一个io密集型的任务,如果这两个任务执行时间相差不大则吞吐量高于单线程任务,如果相差太大则没必要进行分解。

Runtime.getRuntime.getAvaliableProcessors 获得cup数量

优先级不同的任务可使用优先级队列pritorityblockqueue来处理

建议使用有界队列,因为出现异常任务积压时可以执行拒绝策略,及时预警

线程池的监控

taskcount :线程池中需要执行的任务数量

completaskcount:线程池已经完成的线程数量

largestpoolsize:线程池中曾经创建过的最大的线程数量

poolsize 线程池中的线程数量

getactivecount:线程池中活动的线程树

可以通过继承线程你来自定义线程池的 beforeExecute afterExecute terminated 方法来对线程池进行监控


本文出自 “iter工作总结” 博客,请务必保留此出处http://5855156.blog.51cto.com/5845156/1965072

java并发的艺术-读书笔记-第九章线程池

标签:java 线程池原理

原文地址:http://5855156.blog.51cto.com/5845156/1965072

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!