java多线程系列文章:
java多线程(一):synchronized 对象锁和类锁的区别
java多线程(二): wait()、sleep()、 join()和yield()区别
java多线程(三):lock方式实现线程同步机制
1.为什么要使用线程池
按我的理解是为了更好的管理线程,减少系统资源的消耗,因为每次创建和销毁一个线程都是要消耗系统资源的,而线程池可以对已有的线程进行复用,而当线程处于空闲超过一定时间会自动帮我们销毁。
2.线程池的参数
1、corePoolSize(核心线程数):当向线程池提交一个任务时,若线程池中的线程数小于核心线程数,即便此时存在空闲线程,也会创建一个新线程来执行该任务。
2、maximumPoolSize(线程池上限大小):线程池所允许的最大线程个数。当向线程池提交一个任务时发现线程数大于核心线程数,任务会提交到工作队列等待,若工作队列已满,则会判断线程池的线程数是否大于等于最大线程数,如果不是则创建新的线程执行任务,如果是则执行拒绝策略。
3、keepAliveTime(线程存活保持时间)当线程池中线程数大于核心线程数时,线程的空闲时间如果超过线程存活时间,那么这个线程就会被销毁,直到线程池中的线程数小于等于核心线程数。
4、workQueue(任务队列):用于传输和保存等待执行任务的阻塞队列。
5、handler(线程饱和策略):当线程池和队列都满了,再加入线程会执行此策略。
3. 线程池工作流程
4.四种常用的线程池
newSingleThreadExecutor(单一线程池),核心线程数和最大线程数都是1,当这个单一线程挂掉后会新创建新的线程。
创建方式:
ExecutorService executorService= Executors.newSingleThreadExecutor();
for (int i = 0 ; i<10; i++){
final int finalI = i;
executorService.execute(new Runnable() {
@Override
public void run() {
Log.e("Tag",Thread.currentThread().getName()+ ","+finalI);
}
});
}
newFixedThreadPool(固定大小线程池),核心线程数和最大线程数大小一样。
创建方式:
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(2);
for (int i = 0 ; i<20; i++){
final int finalI = i;
fixedThreadPool.execute(new Runnable() {
@Override
public void run() {
Log.e("Tag",Thread.currentThread().getName()+ ","+finalI);
}
});
}
newCachedThreadPool(可缓存的线程池),核心线程数为0,最大线程数为Integer最大值大小。当线程处于空闲,时间超过60秒后会自动销毁。
ExecutorService cachedThreadPool= Executors.newCachedThreadPool();
for (int i = 0 ; i<200; i++){
final int finalI = i;
cachedThreadPool.execute(new Runnable() {
@Override
public void run() {
Log.e("Tag",Thread.currentThread().getName()+ ","+finalI);
}
});
}
newScheduledThreadPool
调度线程池,即按一定的周期执行任务