本文共 9312 字,大约阅读时间需要 31 分钟。
Android中,用ThreadPoolExecutor来实现线程池的配置。
ThreadPoolExecutor的构造方法有四个,其实现如下:
``` public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) { this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, Executors.defaultThreadFactory(), defaultHandler); }public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueueworkQueue, ThreadFactory threadFactory) { this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, defaultHandler);}public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue workQueue, RejectedExecutionHandler handler) { this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, Executors.defaultThreadFactory(), handler);}public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit,BlockingQueue workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) { if (corePoolSize < 0 || maximumPoolSize <= 0 || maximumPoolSize < corePoolSize || keepAliveTime < 0) throw new IllegalArgumentException(); if (workQueue == null || threadFactory == null || handler == null) throw new NullPointerException(); this.corePoolSize = corePoolSize; this.maximumPoolSize = maximumPoolSize; this.workQueue = workQueue; this.keepAliveTime = unit.toNanos(keepAliveTime); this.threadFactory = threadFactory; this.handler = handler;}```
corePoolSize
程池中的核心线程数,也就是是线程池中的最小线程数; 核心线程在allowCoreThreadTimeout被设置为true时会超时退出,默认情况下不会退出;maximumPoolSize
最大线程池大小,当活动线程数达到这个值,后续任务会被阻塞keepAliveTime
线程池中超过corePoolSize数目的非核心线程最大存活时间;闲置时的超时时长,超过这个值后,闲置线程就会被回收unit
keepAliveTime 参数的时间单位。这是一个枚举,workQueue
执行前用于保持任务的队列,也就是线程池的缓存队列。此队列仅保持由 execute 方法提交的 Runnable 任务threadFactory
线程工厂,为线程池提供创建新线程的功能,它是一个接口,只有一个方法:Thread newThread(Runnable r)
RejectedExecutionHandler
线程池对拒绝任务的处理策略。一般是队列已满或者无法成功执行任务,这时ThreadPoolExecutor会调用handler的rejectedExecution方法来通知调用者ThreadPoolExecutor默认有四个拒绝策略:1、ThreadPoolExecutor.AbortPolicy() 直接抛出异常RejectedExecutionException 2、ThreadPoolExecutor.CallerRunsPolicy() 直接调用run方法并且阻塞执行 3、ThreadPoolExecutor.DiscardPolicy() 直接丢弃后来的任务 4、ThreadPoolExecutor.DiscardOldestPolicy() 丢弃在队列中队首的任务
也可以自己继承RejectedExecutionHandler来写拒绝策略.
一个任务通过 execute(Runnable)方法被添加到线程池,任务就是一个 Runnable类型的对象,任务的执行方法就是Runnable类型对象的run()方法。
public class ThreadTestActivity extends AppCompatActivity { private final int CORE_POOL_SIZE = 1;//核心线程数 private final int MAX_POOL_SIZE = 3;//最大线程数 private final int BLOCK_SIZE = 2;//阻塞队列大小 private final long KEEP_ALIVE_TIME = 2;//空闲线程超时时间 private ThreadPoolExecutor executorPool; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_thread_test); //创建线程池 // 创建一个核心线程数为3、最大线程数为8,缓存队列大小为5的线程池 executorPool = new ThreadPoolExecutor(CORE_POOL_SIZE, MAX_POOL_SIZE, KEEP_ALIVE_TIME, TimeUnit.SECONDS, new ArrayBlockingQueue(BLOCK_SIZE), Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy()); executorPool.allowCoreThreadTimeOut(true); } public void begin(View view) { for (int num = 0; num < 6; num++) {//每个500ms添加一个任务到队列中 try { Li("execute");// 监听相关数据 executorPool.execute(new WorkerThread("thread-" + num)); } catch (Exception e) { Log.e("threadtest", "AbortPolicy..."); } } // 20s后,所有任务已经执行完毕,我们在监听一下相关数据 new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(20 * 1000); } catch (Exception e) { } Li("monitor after"); } }).start(); } private void Li(String mess) { Log.i("threadtest", "monitor " + mess + " CorePoolSize:" + executorPool.getCorePoolSize() + " PoolSize:" + executorPool.getPoolSize() + " MaximumPoolSize:" + executorPool.getMaximumPoolSize() + " ActiveCount:" + executorPool.getActiveCount() + " TaskCount:" + executorPool.getTaskCount() ); }}// 模拟耗时任务public class WorkerThread implements Runnable { private String threadName; public WorkerThread(String threadName) { this.threadName = threadName; } @Override public synchronized void run() { int i = 0; boolean flag = true; try { while (flag) { Thread.sleep(1000); i++; Log.e("threadtest", "WorkerThread " + threadName + " " + i); if (i >2) flag = false; } } catch (InterruptedException e) { e.printStackTrace(); } } public String getThreadName() { return threadName; }}
日志信息:
下面就来对日志信息进行分析:
ThreadPoolExecutor.AbortPolicy()
也就是直接抛出异常,也就是我们日志的第7行executorPool.allowCoreThreadTimeOut(true)
,所以这时处于空闲状态的核心线程也会被回收,这时池中的线程数为0其实,本应该先说官方定义的这四种线程池,然后再说自定义线程池,但是考虑到里边的一些配置参数,所以本帖先利用自定义线程池把各个配置参数理一下,然后再讲官方定义的四种线程池,这样也便于理解官方定义的这四种线程池
这四种线程池都是通过Executors的工厂方法来实现他是一种数量固定的线程池,且任务队列也没有大小限制;
它只有核心线程,且这里的核心线程也没有超时限制,所以即使线程处于空闲状态也不会被回收,除非线程池关闭; 当所有的任务处于活动状态,新任务都处于等待状态,知道所有线程空闲出来; 因为它不会被回收,所以它能更快的响应; 源码:public static ExecutorService newFixedThreadPool(int nThreads) { return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue()); }
实现:
ExecutorService service = Executors.newFixedThreadPool(3); service.execute(new WorkerThread("thread-" + num));
无界线程池,可以进行自动线程回收
他是一种线程数量不固定的线程池; 它只有非核心线程,且最大线程数为Integer.MAX_VALUE,也就是说线程数可以任意大; 当池中的线程都处于活动状态时,会创建新的线程来处理任务,否则会利用空闲线程来处理任务;所以,任何添加进来的任务都会被立即执行; 池中的空闲线程都有超时限制,为60s,超过这个限制就会被回收,当池中的所有线程都处于闲置状态时,都会因超时而被回收,这个时候,她几乎不占用任何系统资源; 适合做大量的耗时较少的任务; 源码:public static ExecutorService newCachedThreadPool() { return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue()); }
实现:
ExecutorService service = Executors.newCachedThreadPool(); service.execute(new WorkerThread("thread-"));
只有一个核心线程,所有任务都在同一线程中按序执行,这样也就不需要处理线程同步的问题;
源码:public static ExecutorService newSingleThreadExecutor() { return new FinalizableDelegatedExecutorService (new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue())); }
实现:
ExecutorService service = Executors.newSingleThreadExecutor(); service.execute(new WorkerThread("thread-"));
它的核心线程数量是固定的,而非核心线程是没有限制的,且非核心线程空闲时会被回收;
适合执行定时任务和具有固定周期的任务 源码:public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) { return new ScheduledThreadPoolExecutor(corePoolSize); } public static ScheduledExecutorService newSingleThreadScheduledExecutor() { return new DelegatedScheduledExecutorService (new ScheduledThreadPoolExecutor(1)); } public ScheduledThreadPoolExecutor(int corePoolSize) { super(corePoolSize, Integer.MAX_VALUE, DEFAULT_KEEPALIVE_MILLIS, MILLISECONDS, new DelayedWorkQueue()); }
实现:
ScheduledExecutorService pool = Executors.newScheduledThreadPool(2); 或 ScheduledExecutorService pool = Executors.newSingleThreadScheduledExecutor(); threadPool.schedule(runnable, 20, TimeUnit.SECONDS);// 20秒后执行任务 或 threadPool.scheduleAtFixedRate(runnable,10,20,TimeUnit.SECONDS);//延迟10s,每20s执行一次任务
由于本人技术有限,避免不了出现一些错误或者理解有偏差描述不清楚的地方,请大家谅解并提醒我:)
更多内容请关注
转载请注明出处!本文转自 一点点征服 博客园博客,原文链接:http://www.cnblogs.com/ldq2016/p/8056744.html,如需转载请自行联系原作者