第四种获取线程的方法:线程池,一个 ExecutorService,它使用可能的几个池线程之一执行每个提交的任务,通常使用 Executors 工厂方法配置。
线程池可以解决两个不同问题:由于减少了每个任务调用的开销,它们通常可以在执行大量异步任务时提供增强的性能,并且还可以提供绑定和管理资源(包括执行
任务集时使用的线程)的方法。每个 ThreadPoolExecutor 还维护着一些基本的统计数据,如完成的任务数。
为了便于跨大量上下文使用,此类提供了很多可调整的参数和扩展钩子 (hook)。但是,强烈建议程序员使用较为方便的 Executors 工厂方法 :
- Executors.newCachedThreadPool()(无界线程池,可以进行自动线程回收)
- Executors.newFixedThreadPool(int)(固定大小线程池)
- Executors.newSingleThreadExecutor()(单个后台线程)
它们均为大多数使用场景预定义了设置.
线程池封装类(android开发中用过):
package com.company; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; /** * @类名: ThreadUtils * @描述: TODO(线程池工具类) * @作者: soyoungboy */ public class ThreadUtils { private static volatile ThreadUtils instance = null; // private constructor suppresses private ThreadUtils() { } public static ThreadUtils getInstance() { // if already inited, no need to get lock everytime if (instance == null) { synchronized (ThreadUtils.class) { if (instance == null) { instance = new ThreadUtils(); } } } return instance; } /** * 初始化的线程数,有待历史的验证,暂时弄4个 */ public ExecutorService threadPool = Executors.newFixedThreadPool(4); /** * 单线程 */ static ExecutorService singleThreadPool = Executors.newSingleThreadExecutor(); /** * 执行延迟任务,类似Timer的效果 */ public ScheduledExecutorService scheduleThreadPool = Executors.newScheduledThreadPool(2); /** * 立即执行任务 * * @param task ThreadUtils.getInstance().excute(run); */ public void excute(Runnable task) { threadPool.execute(task); } /** * 单线程持操作,主要用于数据库的读写异步操作 * * @param task ThreadUtils.getInstance().excuteSingleThread(run); * @return */ public Future excuteSingleThread(Runnable task) { return singleThreadPool.submit(task); } ; /** * 延后执行任务 * * @param task * @param delay ThreadUtils.getInstance().schedule(run,1000); */ public void schedule(Runnable task, long delay) { scheduleThreadPool.schedule(task, delay, TimeUnit.MILLISECONDS); } /** * @return void 返回类型 * @Title: shutdownThreadPool * @Description: TODO() */ public void shutdownThreadPool() { threadPool.shutdownNow(); } /** * @return void 返回类型 * @Title: shutdownThreadPool * @Description: TODO() */ public void shutdownScheduleThreadPool() { scheduleThreadPool.shutdownNow(); } /** * @return void 返回类型 * @Title: shutdownSingleThreadPool * @Description: TODO(单线程池销毁操作) */ public void shutdownSingleThreadPool() { singleThreadPool.shutdownNow(); } }
Demo:
public class TestScheduledThreadPool { public static void main(String[] args) throws Exception { ThreadUtils instance = ThreadUtils.getInstance(); for (int i = 0; i < 10; i++) { instance.schedule(() -> { int num = new Random().nextInt(100);//生成随机数 System.out.println(Thread.currentThread().getName() + " : " + num); }, 3); } instance.shutdownScheduleThreadPool(); } }
结果:
pool-3-thread-2 : 79 pool-3-thread-1 : 87 pool-3-thread-2 : 44 pool-3-thread-1 : 90 pool-3-thread-2 : 0 pool-3-thread-1 : 77 pool-3-thread-2 : 20 pool-3-thread-1 : 63 pool-3-thread-2 : 68 pool-3-thread-1 : 15