持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第30天,点击查看活动详情
前面我们介绍了简单的Thread使用、实现runnable接口的使用以及具有handler功能的HandlerThread的使用,他们都是对线程的直接或间接使用,亦或是封装好的Thread的组件比Thread的功能更丰富,不管是Thread的使用还是HandlerThread的封装使用,他们都是开辟一个线程空间来操作或者执行用户的操作,对已经存在在项目里的线程都无法做到完全的管理和资源分配,简单的说就是我们无法知道我们迭代了很多功能的时候项目中哪里使用了线程,会不会因为某些使用导致出现卡顿或者因为线程不安全导致的内存泄漏,因为没有及时释放资源导致的资源浪费等等问题,那么我们就需要一个工具来管理我们线程中用到的所有线程,统一出口,统一管理,统一消费,统一释放,这样是不是可以大大提升我们项目的维护成本同时也可以及时定位因为线程使用不当造成的问题,那么我们就需要用到我们的线程管理工具,线程池-ThreadPool。
ThreadPool的定义及使用
ThreadPool:一种线程使用模式,线程池维护着项目中的多个线程,等待着监督管理者分配可并发执行的任务。线程池,它本质上就是一种对象池,用于管理线程资源,在 任务调用前从线程池中取线程,任务完成后,把线程归还线程池,它的好处就是可以使用这种重复利用机制,避免直接创建线程的资源浪费。
ThreadPool的使用
private static ExecutorService THREAD_POOL_EXECUTOR;
private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
private static final int CORE_POOL_SIZE = Math.max(2, Math.min(CPU_COUNT - 1, 4));
private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2;
private static final int KEEP_ALIVE_SECONDS = 60;
private static final BlockingQueue<Runnable> sPoolWorkQueue = new LinkedBlockingQueue<>(8);
private static final ThreadFactory sThreadFactory = new ThreadFactory() {
private final AtomicInteger mCount = new AtomicInteger(1);
public Thread newThread(Runnable r) {
return new Thread(r, "MangoTask #" + mCount.getAndIncrement());
}
};
上面是我们项目中定义的线程池, 对于线程池的管理类,我们一般都使用单例来实现:
private static MyThreadPool instance;
private MyThreadPool() {
initThreadPool();
}
public static MyThreadPool getInstance() {
if (instance == null) {
synchronized (MyThreadPool.class) {
if (instance == null) {
instance = new MyThreadPool();
}
}
}
return instance;
}
下面是初始化线程池:
private void initThreadPool() {
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE_SECONDS, TimeUnit.SECONDS,
sPoolWorkQueue, sThreadFactory, new RejectedHandler()) {
@Override
public void execute(Runnable command) {
super.execute(command);
}
};
//允许核心线程空闲超时时被回收
threadPoolExecutor.allowCoreThreadTimeOut(true);
THREAD_POOL_EXECUTOR = threadPoolExecutor;
}
使用的话直接调用excute方法就好了:
public void execute(Runnable command) {
THREAD_POOL_EXECUTOR.execute(command);
}
是不是很简单,设置的内容大家可以根据自己的需要来修改适合自己的。简单使用可以直接copy上面内容。