您的位置:首页 > 移动开发 > Android开发

android线程池详解(一)

2016-07-04 16:12 591 查看
闲暇时间,写写自己的的工作中对使用线程池的一些理解,本人也有些懒里面有些东西就直接复制他人的博客,相互学习,共同进步啦,有解释不对的地方,希望大神们提出来!

好了下面学习阶段

1.首先来讲一下什么是线程池

线程池是指在初始化一个多线程应用程序过程中创建一个线程集合,然后在需要执行新的任务时重用这些线程而不是新建一个线程。线程池中线程的数量通常完全取决于可用内存数量和应用程序的需求。然而,增加可用线程数量是可能的。线程池中的每个线程都有被分配一个任务,一旦任务已经完成了,线程回到池子中并等待下一次分配任务。(通俗的讲,线程池是一个多条线程的集合,需要执行任务的时候就去取一条线程来用,用完了在放回去)

2.使用线程的的好处

①减少开销,提高性能(线程重用,避免了线程重复创建和销毁)

②防止内存过度消耗,控制活动线程的数量,防止并发线程过多

3.线程池的组成部分
一个比较简单的线程池至少应包含线程池管理器、工作线程、任务列队、任务接口等部分。其中线程池管理器的作用是创建、销毁并管理线程池,将工作线程放入线程池中;工作线程是一个可以循环执行任务的线程,在没有任务是进行等待;任务列队的作用是提供一种缓冲机制,将没有处理的任务放在任务列队中;任务接口是每个任务必须实现的接口,主要用来规定任务的入口、任务执行完后的收尾工作、任务的执行状态等,工作线程通过该接口调度任务的执行。

线程池管理器至少有下列功能:创建线程池,销毁线程池,添加新任务。

工作线程是一个可以循环执行任务的线程,在没有任务时将等待。

任务接口是为所有任务提供统一的接口,以便工作线程处理。任务接口主要规定了任务的入口,任务执行完后的收尾工作,任务的执行状态等。

4.线程池的创建

Java中由ThreadPoolExecutor以及它的子类ScheduledThreadPoolExecutor来创建线程池,现在先来讲讲简单的线程创建,后面的文章中在回头详细的讲解一下ThreadpoolExecutor。

Java中工厂类Executors提供了四种线程池的创建

①newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。

②newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。

③newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。

④newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。

示例

创建缓存线程池

ExecutorService cachedPool = Executors.newCachedThreadPool();


cachedPool.execute(new Runnable() {
@Override
public void run() {
//线程任务
}
});


<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">定长线程池</span>


ExecutorService fixedPool = Executors.newFixedThreadPool(5);
fixedPool.execute(new Runnable() {
@Override
public void run() {
//线程任务
}
});


单线程线程池的

ExecutorService singlePool=Executors.newSingleThreadExecutor();
singlePool.execute(new Runnable() {
@Override
public void run() {
//执行任务代码
}
});


定时线程池

在ExecutorService的基础上又提供了ScheduledExecutorService子类,来按时间安排执行任务的功能,它提供的方法主要有:

schedule(task,initDelay):安排所提交的Callable或Runnable任务在initDelay指定的时间后执行。

scheduleAtFixedRate():安排所提交的Runnable任务按指定的间隔重复执行

scheduleWithFixedDelay():安排所提交的Runnable任务在每次执行完后,等待delay所指定的时间后重复执行。

//创建定长为5的定时线程池
ScheduledExecutorService schedledPool=Executors.newScheduledThreadPool(5);


//定时2秒执行任务
schedledPool.schedule(new Runnable() {
@Override
public void run() {
//定时执行的
}
}, 2, TimeUnit.SECONDS);

//表示5秒后开始执行循环任务,循环任务间隔一秒
schedledPool.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
//定时执行的

}
}, 5, 1, TimeUnit.SECONDS);
//表示5秒后开始执行循环任务,循环任务间隔二秒
schedledPool.scheduleWithFixedDelay(new Runnable() {
@Override
public void run() {
//定时执行的
}
},5,2,TimeUnit.SECONDS);


执行定期循环任务的时候有一点需要注意了

scheduleAtFixedRate和scheduleWithFixedDelay的区别

从字面意思来看ScheduleAtFixedRate是固定速率,SchedluewithFexedDealay相对固定的延迟

经过几次demo的测试发现

图片一


图片二



从测试打印的log来看,两个程序延迟的都是2秒,而ScheduleAtFixedRate比SchedluewithFexedDealay多执行了近一倍,然后在继续测试,下面的代码我就不帖出来了,经过多次测试和log打印从而得出结论

ScheduleAtFixedRate 表示在上一个个任务开始执行之后延迟 多少秒之后再执行, 是从上一个任务开始时开始计算 但是还是会等上一个任务执行完之后,下一个任务才开始执行,最后的结果,如果任务执行时间过长超过了,延迟时间,就是感觉延迟失去 了作用

SchedluewithFexedDealay 表示在上一个个任务结束执行之后延迟 多少秒之后再执行, 是从上一个任务结束时开始计算

关闭线程池:

当没有任务可运行的时候关闭线程池


schedledPool.shutdown();


//立即关闭线程池,不管任务是否执行完毕
schedledPool.shutdownNow();




内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息