虽然说RxJava 与RxAndroid 已经能很好的处理多线程的问题,但是我们还是要总结一下线程池的使用
为什么需要使用线程池?线程的频发创建,需要时间,也会加大系统的开销,最简单的办法就是复用,也因此产生线程池,产生线程池的核心就是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, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory) { this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, defaultHandler); } public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, RejectedExecutionHandler handler) { this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, Executors.defaultThreadFactory(), handler); } public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> 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 | 线程池大小,当任务的线程数超过其值时就会放入到缓存队列中 |
maximumPoolSize | 线程池最大线程数,表示线程池中最多能创建的线程数量 |
keepAliveTime | 表示线程没有任务执行最等待多时时间而终止,条件: 1:当前线程池中的线程数>corePoolSize 2:allowCoreThreadTimeOut(booleanvalue)调用 |
TimeUnit | 时间单位 |
BlockingQueue | 阻塞队列,其子类非常多: 常用的用:ArrayBlockingQueue LinkedBlockingQueue SynchronousQueue LinkdeBlockingQueue |
threadFactory | 创建线程的工厂 |
handler | ThreadPoolExecutor已经实现四个(内部类):分别是:AbortPolicy//抛出异常 DiscardPolicy //丢弃任务 DiscardOldestPolicy //丢弃最前面的任务,然后执行新的任务 CallerRunsPolicy //由线程处理任务 |
ThreadPoolExecutor常用的方法:
public void execute(Runnable command) |
执行一个任务 |
Future<?> submit(Runnable task); <T> Future<T> submit(Runnable task, T result);Future<?> submit(Runnable task); |
执行一个任务 重载形式非常多,可以要求返回结果 可以是Future 可以有执行状态和返回值等 |
shutDown() | interuppt空闲线程,会等待线程执行完成,不再执行新的任务 |
shutDownNow() | interuppt所有线程,尝试终止正在执行的线程 |
实例:
package com.example; import com.example.utils.LogUtils; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; /** * @author xuanyouwu * @email [email protected] * @time 2016-05-04 16:38 */ public class ThreadPoolStudy { static ThreadPoolExecutor threadPoolExecutor; public static void main(String[] args) throws Exception { threadPoolExecutor = new ThreadPoolExecutor(3, 10, 2, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(3)); for (int i = 0; i < 100; i++) { threadPoolExecutor.execute(new Task()); } } static class Task implements Runnable { @Override public void run() { LogUtils.d("------>excute:Thread:" + Thread.currentThread().getId()+" PoolSiz:"+threadPoolExecutor.getPoolSize()+" ActiveCount:"+threadPoolExecutor.getActiveCount()+" queueSize:" +threadPoolExecutor.getQueue().size()+" CompletedTaskCount:"+threadPoolExecutor.getCompletedTaskCount()); try { Thread.currentThread().sleep(3000); } catch (InterruptedException e) { } } } }
------>excute:Thread:12 PoolSiz:5 ActiveCount:6 queueSize:3 CompletedTaskCount:0
Exception in thread "main" java.util.concurrent.RejectedExecutionException: Task com.example.ThreadPoolStudy$Task@5cad8086 rejected from java.util.concurrent.ThreadPoolExecutor@6e0be858[Running, pool size = 10, active threads = 10, queued tasks = 3, completed tasks = 0]
------>excute:Thread:17 PoolSiz:9 ActiveCount:9 queueSize:3 CompletedTaskCount:0
------>excute:Thread:20 PoolSiz:9 ActiveCount:10 queueSize:3 CompletedTaskCount:0
------>excute:Thread:15 PoolSiz:7 ActiveCount:7 queueSize:3 CompletedTaskCount:0
------>excute:Thread:14 PoolSiz:6 ActiveCount:6 queueSize:3 CompletedTaskCount:0
------>excute:Thread:18 PoolSiz:9 ActiveCount:9 queueSize:3 CompletedTaskCount:0
at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2047)
------>excute:Thread:19 PoolSiz:9 ActiveCount:9 queueSize:3 CompletedTaskCount:0
at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:823)
出现了异常,
从源码中可以看到 推荐使用Excutors来创建线程池
public static ExecutorService newWorkStealingPool() { return new ForkJoinPool (Runtime.getRuntime().availableProcessors(), ForkJoinPool.defaultForkJoinWorkerThreadFactory, null, true); }
可惜是java 1.8才有的
推荐下面几种写法:
用法实例:newCachedThreadPool/** * return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>()); */ Executors.newCachedThreadPool(); /** * return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()); */ Executors.newFixedThreadPool(100); /** * return new FinalizableDelegatedExecutorService (new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>())); */ Executors.newSingleThreadExecutor();
ExecutorService executorService = Executors.newCachedThreadPool(); for(int i=0;i<50;i++) { executorService.execute(new Runnable() { @Override public void run() { try { Thread.currentThread().sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } LogUtils.d("---------->Thread:"+Thread.currentThread().getId()); } }); }
---------->Thread:13
---------->Thread:21
---------->Thread:15
---------->Thread:18
---------->Thread:19
---------->Thread:17
---------->Thread:20
---------->Thread:12
---------->Thread:16
---------->Thread:14
---------->Thread:30
---------->Thread:29
---------->Thread:28
---------->Thread:27
---------->Thread:25
---------->Thread:26
---------->Thread:24
---------->Thread:23
---------->Thread:22
---------->Thread:38
---------->Thread:41
---------->Thread:40
---------->Thread:39
---------->Thread:37
---------->Thread:34
---------->Thread:36
---------->Thread:35
---------->Thread:31
---------->Thread:33
---------->Thread:32
---------->Thread:46
---------->Thread:50
---------->Thread:48
---------->Thread:49
---------->Thread:51
---------->Thread:44
---------->Thread:45
---------->Thread:42
---------->Thread:43
---------->Thread:47
---------->Thread:55
---------->Thread:61
---------->Thread:58
---------->Thread:57
---------->Thread:60
---------->Thread:59
---------->Thread:56
---------->Thread:54
---------->Thread:52
---------->Thread:53
例子:固定线程newFixedThreadPool
ExecutorService executorService = Executors.newFixedThreadPool(3); for(int i=0;i<50;i++) { executorService.execute(new Runnable() { @Override public void run() { try { Thread.currentThread().sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } LogUtils.d("---------->Thread:"+Thread.currentThread().getId()); } }); } executorService.shutdown();运行结果:
---------->Thread:14
---------->Thread:12
---------->Thread:13
---------->Thread:13
---------->Thread:14
---------->Thread:12
---------->Thread:13
---------->Thread:14
---------->Thread:12
---------->Thread:12
.....
例子:newSingleThreadExecutor
executorService=Executors.newSingleThreadExecutor(); for(int i=0;i<50;i++) { executorService.execute(new Runnable() { @Override public void run() { try { Thread.currentThread().sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } LogUtils.d("---------->Thread:"+Thread.currentThread().getId()); } }); } executorService.shutdown();
---------->Thread:12
---------->Thread:12
---------->Thread:12
---------->Thread:12
---------->Thread:12
......
线程的优先级:
/** * The minimum priority that a thread can have. */ public final static int MIN_PRIORITY = 1; /** * The default priority that is assigned to a thread. */ public final static int NORM_PRIORITY = 5; /** * The maximum priority that a thread can have. */ public final static int MAX_PRIORITY = 10;
设置线程的优先级需要ThreadFacotry
ThreadFactory threadFactory_MAX_PRIORITY = new ThreadFactory() { @Override public Thread newThread(Runnable r) { Thread thread = new Thread(r); thread.setPriority(Thread.MAX_PRIORITY); return thread; } }; ThreadFactory threadFactory_MIN_PRIORITY = new ThreadFactory() { @Override public Thread newThread(Runnable r) { Thread thread = new Thread(r); thread.setPriority(Thread.MIN_PRIORITY); return thread; } }; ThreadFactory threadFactory_NORMAL_PRIORITY = new ThreadFactory() { @Override public Thread newThread(Runnable r) { Thread thread = new Thread(r); thread.setPriority(Thread.NORM_PRIORITY); return thread; } }; ExecutorService executorService_MAX = Executors.newCachedThreadPool(threadFactory_MAX_PRIORITY); for (int i = 0; i < 10; i++) { executorService_MAX.execute(new Runnable() { @Override public void run() { try { Thread.currentThread().sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } LogUtils.d("---------->Thread:" + Thread.currentThread().getId() + " threadPripiry:" + Thread.currentThread().getPriority()); } }); } executorService_MAX.shutdown(); ExecutorService executorService_NOR = Executors.newCachedThreadPool(threadFactory_NORMAL_PRIORITY); for (int i = 0; i < 10; i++) { executorService_NOR.execute(new Runnable() { @Override public void run() { try { Thread.currentThread().sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } LogUtils.d("---------->Thread:" + Thread.currentThread().getId() + " threadPripiry:" + Thread.currentThread().getPriority()); } }); } executorService_NOR.shutdown(); ExecutorService executorService_MIN = Executors.newCachedThreadPool(threadFactory_MIN_PRIORITY); for (int i = 0; i < 10; i++) { executorService_MIN.execute(new Runnable() { @Override public void run() { try { Thread.currentThread().sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } LogUtils.d("---------->Thread:" + Thread.currentThread().getId() + " threadPripiry:" + Thread.currentThread().getPriority()); } }); } executorService_MIN.shutdown();
---------->Thread:16 threadPripiry:10
---------->Thread:15 threadPripiry:10
---------->Thread:18 threadPripiry:10
---------->Thread:21 threadPripiry:10
---------->Thread:14 threadPripiry:10
---------->Thread:26 threadPripiry:5
---------->Thread:19 threadPripiry:10
---------->Thread:20 threadPripiry:10
---------->Thread:13 threadPripiry:10
---------->Thread:17 threadPripiry:10
---------->Thread:12 threadPripiry:10
---------->Thread:30 threadPripiry:5
---------->Thread:29 threadPripiry:5
---------->Thread:31 threadPripiry:5
---------->Thread:28 threadPripiry:5
---------->Thread:24 threadPripiry:5
---------->Thread:27 threadPripiry:5
---------->Thread:25 threadPripiry:5
---------->Thread:22 threadPripiry:5
---------->Thread:23 threadPripiry:5
---------->Thread:32 threadPripiry:1
---------->Thread:34 threadPripiry:1
---------->Thread:33 threadPripiry:1
---------->Thread:35 threadPripiry:1
---------->Thread:39 threadPripiry:1
---------->Thread:36 threadPripiry:1
---------->Thread:38 threadPripiry:1
---------->Thread:37 threadPripiry:1
---------->Thread:41 threadPripiry:1
---------->Thread:40 threadPripiry:1