理解线程池的笔记
2015-10-15 10:25
357 查看
资料链接http://blog.csdn.net/weihan1314/article/details/7983725点击打开链接
知道线程池的人应该都知道线程池的优点,以下列出:
1,重用线程池中的线程,避免因为频繁的创建线程带来的性能下降;
2,能有效的控制线程池的最大并发数,避免以为其共同抢占资源而造成的阻塞,
3,能够对线程进行简单的管理,提供制定间隔和定时执行。
线程池java提供了一个借口Executor,真正的线程池实现靠下面的ThreadPoolExecutor,提供了一系列的参数来配置线程池,通过配置参数来创建不同的线程池,因此我们重点理解ThreadPoolExecutor,
线程池为无限大,当执行第二个任务时第一个任务已经完成,会复用执行第一个任务的线程,而不用每次新建线程。 (2). newFixedThreadPool
创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。示例代码如下:Java
因为线程池大小为3,每个任务输出index后sleep 2秒,所以每两秒打印3个数字。
定长线程池的大小最好根据系统资源进行设置。如Runtime.getRuntime().availableProcessors()。可参考PreloadDataCache。
(3) newScheduledThreadPool
创建一个定长线程池,支持定时及周期性任务执行。延迟执行示例代码如下:
Java
表示延迟3秒执行。 定期执行示例代码如下:Java
表示延迟1秒后每3秒执行一次。
ScheduledExecutorService比Timer更安全,功能更强大,后面会有一篇单独进行对比。
(4)、newSingleThreadExecutor
创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。示例代码如下:
Java
个人总结:其实最常用的是newFixedThreadPool来创建线程池,当然了我们在实际应用中使用线程池时可以配置信号量来优化任务管理,而不是一直将任务加入到任务队列,这样做对安卓的性能不是很好,最常见的就是图片加载框架,当任务来临时,并且任务数量未达到核心线程数,此时我们可以将任务加入我们自定义的任务队列中等待有闲置的核心线程,那么怎么控制任务数量达到核心线程数时等待呢,我们可以创建一个信号量,其数量的核心线程数量一致,如下:
// 创建线程池
mThreadPool = Executors.newFixedThreadPool(threadCount);
mTaskQueue = new LinkedList<Runnable>();
mType = type;
mSemaphoreThreadPool = new Semaphore(threadCount);
每当来任务时,
// 线程池去取出一个任务进行执行
mThreadPool.execute(getTask());
try
{
mSemaphoreThreadPool.acquire();
} catch (InterruptedException e)
{
}
此时信号量阻塞一个,当达到核心线程数量时信号量使用完了,新来的任务,则不接受,只有当任务执行完之后调用release()方法释放一个信号量,
mSemaphoreThreadPool.release();
再来任务时才会调用线程池中的线程进行任务处理,至此大概就总结完了,参考了很多大神的文章,自己总结来当笔记学习。
知道线程池的人应该都知道线程池的优点,以下列出:
1,重用线程池中的线程,避免因为频繁的创建线程带来的性能下降;
2,能有效的控制线程池的最大并发数,避免以为其共同抢占资源而造成的阻塞,
3,能够对线程进行简单的管理,提供制定间隔和定时执行。
线程池java提供了一个借口Executor,真正的线程池实现靠下面的ThreadPoolExecutor,提供了一系列的参数来配置线程池,通过配置参数来创建不同的线程池,因此我们重点理解ThreadPoolExecutor,
ThreadPoolExecutor(int corePoolSize, int maximumPoolSize,
long keepAliveTime, TimeUnit unit,
BlockingQueue<Runnable> workQueue,
RejectedExecutionHandler handler);
corePoolSize: 线程池维护线程的最少数量,即核心线程,如果allowCoreThreadTimeOut设置为true,即核心线程超时会被销毁,一般配置这个,所以核心线程会一直存在,不会被销毁。
maximumPoolSize:线程池维护线程的最大数量,
keepAliveTime: 线程池维护线程所允许的空闲时间
unit: 线程池维护线程所允许的空闲时间的单位
workQueue: 线程池所使用的缓冲队列
handler: 线程池对拒绝任务的处理策略
以此创建的线程池在执行任务时大致遵循以下原则,
1,任务来临时,当活动线程数未超过核心线程数量时会直接使用剩余的核心线程执行任务,
2,如果线程池中的活动线程数量已经达到核心线程的数量,则会将人物加入到任务队列中排队等待执行,
3,如果在步骤二中无法讲任务插入任务对列,证明任务队列已经满了,这个时候再来任务则会立即重新启动一个非核心线程来执行任务,但是此时如果超过设置的最大活动线程数量,那么系统会拒绝此任务,会抛出异常。
其实在安卓的asynctask中就使用了线程池来操作任务,他的源码中配置了核心线程数量为cpu核心数加1,任务队列最多可以容纳128个任务,最大线程数为cpu狠心数*2+1,也就是任务队列已满时还是可以启动非核心线程来执行任务。
以下内容为转载,地址http://www.trinea.cn/android/java-android-thread-pool/,
2、Java
线程池
Java通过Executors提供四种线程池,分别为:
newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。
newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
(1). newCachedThreadPool
创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。示例代码如下:
Java
1234567891011121314151617 | ExecutorService cachedThreadPool = Executors.newCachedThreadPool();for (int i = 0; i < 10; i++) { final int index = i; try { Thread.sleep(index * 1000); } catch (InterruptedException e) { e.printStackTrace(); } cachedThreadPool.execute(new Runnable() { @Override public void run() { System.out.println(index); } });} |
创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。示例代码如下:Java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | ExecutorServicefixedThreadPool=Executors.newFixedThreadPool(3); for(inti=0;i<10;i++){ finalintindex=i; fixedThreadPool.execute(newRunnable(){ @Override publicvoidrun(){ try{ System.out.println(index); Thread.sleep(2000); }catch(InterruptedExceptione){ // TODO Auto-generated catch block e.printStackTrace(); } } }); } |
定长线程池的大小最好根据系统资源进行设置。如Runtime.getRuntime().availableProcessors()。可参考PreloadDataCache。
(3) newScheduledThreadPool
创建一个定长线程池,支持定时及周期性任务执行。延迟执行示例代码如下:
Java
12345678 | ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);scheduledThreadPool.schedule(new Runnable() { @Override public void run() { System.out.println("delay 3 seconds"); }}, 3, TimeUnit.SECONDS); |
1 2 3 4 5 6 7 | scheduledThreadPool.scheduleAtFixedRate(newRunnable(){ @Override publicvoidrun(){ System.out.println("delay 1 seconds, and excute every 3 seconds"); } },1,3,TimeUnit.SECONDS); |
ScheduledExecutorService比Timer更安全,功能更强大,后面会有一篇单独进行对比。
(4)、newSingleThreadExecutor
创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。示例代码如下:
Java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | ExecutorServicesingleThreadExecutor=Executors.newSingleThreadExecutor(); for(inti=0;i<10;i++){ finalintindex=i; singleThreadExecutor.execute(newRunnable(){ @Override publicvoidrun(){ try{ System.out.println(index); Thread.sleep(2000); }catch(InterruptedExceptione){ // TODO Auto-generated catch block e.printStackTrace(); } } }); } |
// 创建线程池
mThreadPool = Executors.newFixedThreadPool(threadCount);
mTaskQueue = new LinkedList<Runnable>();
mType = type;
mSemaphoreThreadPool = new Semaphore(threadCount);
每当来任务时,
// 线程池去取出一个任务进行执行
mThreadPool.execute(getTask());
try
{
mSemaphoreThreadPool.acquire();
} catch (InterruptedException e)
{
}
此时信号量阻塞一个,当达到核心线程数量时信号量使用完了,新来的任务,则不接受,只有当任务执行完之后调用release()方法释放一个信号量,
mSemaphoreThreadPool.release();
再来任务时才会调用线程池中的线程进行任务处理,至此大概就总结完了,参考了很多大神的文章,自己总结来当笔记学习。
相关文章推荐
- Android加载Html的方法
- NVIDIA Jetson TK1开发板上手
- 17.1.5.1 Checking Replication Status 检查复制状态:
- iOS 全局变量PCH文件的使用
- 【iOS】网络操作与AFNetworking
- hdu 1394 Minimum Inversion Number(成段更新)
- iOS之通知传值的使用
- OpenWRT GPIO人口控制 WLED
- 使用T4模板生成代码的学习
- 技术文摘13 郑钧 泰岳 技术 资料 源码 UI tinypng 保质压缩 github 大神 高仿 VVDocumenter-Xcode 工具 唐巧
- .公司域名总量TOP15 :新网、万网、中资源稳居前三
- C++读写文件
- Android笔记8 SharedPreference
- CloudStack 4.4+KVM之虚拟机模板创建
- 在VS中使用TinyFox调试OWIN应用(转)
- 【正则表达式】js删除末尾的0
- 解决eclipse创建Maven项目后无法生成src/main/java资源文件夹的方法
- c#相关连接
- 正则表达式
- jquery查看当前平台