一.为什么要用线程池
1.减少了创建和销毁线程的次数,每个工作线程都可以被重复利用,可执行多个任务。
2.可以根据系统的承受能力,调整线程池中工作线线程的数目,防止因为消耗过多的内存,而把服务器累趴下(每个线程需要大约1MB内存,线程开的越多,消耗的内存也就越大,最后死机)。
Java里面线程池的顶级接口是Executor,但是严格意义上讲Executor并不是一个线程池,而只是一个执行线程的工具。真正的线程池接口是ExecutorService。
比较重要的几个类:
ExecutorService | 真正的线程池接口。 |
ScheduledExecutorService | 能和Timer/TimerTask类似,解决那些需要任务重复执行的问题。 |
ThreadPoolExecutor | ExecutorService的默认实现。 |
ScheduledThreadPoolExecutor | 继承ThreadPoolExecutor的ScheduledExecutorService接口实现,周期性任务调度的类实现。 |
要配置一个线程池是比较复杂的,尤其是对于线程池的原理不是很清楚的情况下,很有可能配置的线程池不是较优的,因此在Executors类里面提供了一些静态工厂,生成一些常用的线程池。
二.线程池的作用
线程池作用就是限制系统中执行线程的数量。
根据系统的环境情况,可以自动或手动设置线程数量,达到运行的最佳效果;少了浪费了系统资源,多了造成系统拥挤效率不高。用线程池控制线程数量,其他线程排队等候。一个任务执行完毕,再从队列的中取最前面的任务开始执行。若队列中没有等待进程,线程池的这一资源处于等待。当一个新任务需要运行时,如果线程池 中有等待的工作线程,就可以开始运行了;否则进入等待队列。
三.线程池划分
从上图我们可以发现Executors提供的线程池大致可分为四种:
newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。
newScheduledThreadPool 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO,优先级)执行。
四.类似定时器:ScheduledExecutorService
ScheduledExecutorService scheduledExecutorService= Executors.newSingleThreadScheduledExecutor();
scheduledExecutorService.scheduleWithFixedDelay
(某个线程, (启动前时间)6,(间隔)6, TimeUnit.SECONDS(单位));// 自动播放
五.针对安卓项目创建的高级线程池
import android.os.Process;
import java.io.File;
import java.io.FileFilter;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Executor;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Pattern;
/**
* Description:线程池
* AUTHOR: Champion Dragon
* created at 2019/8/23
**/
public class ThreadFactoryUtil {
/**
* 任务执行数.
*/
public static Executor mExecutorService = null;
/**
* 保存线程数量 .
*/
private static final int CORE_POOL_SIZE = 5;
/**
* 最大线程数数 .
*/
private static final int MAXIMUM_POOL_SIZE = 64;
/**
* 活动线程数量 .
*/
private static final int KEEP_ALIVE = 5;
/**
* 线程工厂 .
*/
private static final ThreadFactory mThreadFactory = new ThreadFactory() {
private final AtomicInteger mCount = new AtomicInteger(1);
public Thread newThread(Runnable r) {
return new Thread(r, "AbThread #" + mCount.getAndIncrement());
}
};
/**
* 队列.
*/
private static final BlockingQueue<Runnable> mPoolWorkQueue = new LinkedBlockingQueue<Runnable>(10);
/**
* 获取执行.
*
* @return the executor service
*/
public static Executor getExecutorService() {
if (mExecutorService == null) {
int numCores = getNumCores();
mExecutorService = new ThreadPoolExecutor(numCores * CORE_POOL_SIZE, numCores * MAXIMUM_POOL_SIZE,
numCores * KEEP_ALIVE, TimeUnit.SECONDS, mPoolWorkQueue, mThreadFactory);
}
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
return mExecutorService;
}
/**
* 获取cpu核心数
*/
public static int getNumCores() {
try {
File dir = new File("/sys/devices/system/cpu/");
File[] files = dir.listFiles(new FileFilter() {
@Override
public boolean accept(File pathname) {
if (Pattern.matches("cpu[0-9]", pathname.getName())) {
return true;
}
return false;
}
});
return files.length;
} catch (Exception e) {
e.printStackTrace();
return 1;
}
}
}
线程池的调用:
Executor mExecutorService= ThreadFactoryUtil.getExecutorService();