Java的线程和线程池的了解
一:概念
在Java中,应用线程来异步执行工作。Java的线程既是工作单元,也是执行机制。从JDK 5开始,把工作单元与执行机制拆散开来。工作单元包含Runnable和Callable,而执行机制由Executor框架提供。
二:什么是Executor框架?
咱们晓得线程池就是线程的汇合,线程池集中管理线程,以实现线程的重用,升高资源耗费,进步响应速度等。线程用于执行异步工作,单个的线程既是工作单元也是执行机制,从JDK1.5开始,为了把工作单元与执行机制分来到,Executor框架诞生了,他是一个用于对立创立与运行的接口。Executor框架实现的就是线程池的性能
三:Executor的构造
Executor框架次要由3大部分组成如下。
1.工作:包含被执行工作须要实现的接口:Runnable接口或Callable接口。
2.工作的执行:包含工作执行机制的外围接口Executor,以及继承自Executor的ExecutorService接口。Executor框架有两个要害类实现了ExecutorService接口(ThreadPoolExecutor和ScheduledThreadPoolExecutor)。
3.异步计算的后果:包含接口Future和实现Future接口的FutureTask类。
Executor框架蕴含的次要的类与接口如下图所示
四:对框架的了解
Executor是一个接口,它是Executor框架的根底,它将工作的提交与工作的执行拆散开来
//我了解的这是一个定义线程一个行为,工作执行,具体交由其实现实现public interface Executor { void execute(Runnable command);}
ExecutorService 也是一个接口 继承Executor接口 扩大Executor
public interface ExecutorService extends Executor {//进行接管新工作,原来的工作继续执行 void shutdown();//进行接管新工作,原来的工作进行执行List<Runnable> shutdownNow();//接管的参数不一样 submit()能够承受runnable无返回值和callable有返回值execute()承受runnable 无返回值<T> Future<T> submit(Callable<T> task);}
AbstractExecutorService 是一个抽象类 实现ExecutorService接口扩大性能
ScheduledExecutorService(提早的线程池服务)是一个接口 继承ExecutorService接口扩大性能
线程池外围类:
ThreadPoolExecutor 继承AbstractExecutorService 的线程池类
public class ThreadPoolExecutor extends AbstractExecutorService {//构造方法//corePoolSize 外围线程 指定了线程池中的线程数量,它的数量决定了增加的工作是开拓新的线程去执行,还是放到workQueue工作队列中去;//maximumPoolSize 指定了线程池中的最大线程数量,这个参数会依据你应用的workQueue工作队列的类型,决定线程池会开拓的最大线程数量;//keepAliveTime 当线程池中闲暇线程数量超过corePoolSize时,多余的线程会在多长时间内被销毁;(闲暇线程包活工夫)//unit:keepAliveTime的单位//workQueue:工作队列,被增加到线程池中,但尚未被执行的工作;它个别分为间接提交队列、有界工作队列、无界工作队列、优先工作队列几种;(阻塞队列长度设置为Integer.MAX_VALUE)//threadFactory:线程工厂,用于创立线程,个别用默认即可;//handler:回绝策略;当工作太多来不及解决时,如何回绝工作; public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, RejectedExecutionHandler handler) { this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, Executors.defaultThreadFactory(), handler); }}//例如线程池外围线程数为1,最大线程数为10,工作队列容量(阻塞队列)queueCapacity也就是BlockingQueue工作10个默认线程池的数量为1,当工作不超过10个,会在工作队列排队期待线程池里一个线程解决当工作>10个,会创立一个新的线程解决当线程数达到最大线程数的时候 RejectedExecutionHandler(工作回绝处理器) 回绝策略
RejectedExecutionHandler(回绝策略) 接口有上面几个实现类 如果没有设置,默认是AbortPolicy,会抛出异样。
AbortPolicy:抛弃工作,抛运行时异样
CallerRunsPolicy:执行工作
DiscardOldestPolicy:从队列中踢出最先进入队列(最初一个执行)的工作
DiscardPolicy: 漠视,什么都不会产生
五:线程池的具体实现类
举例:Glide的线程池实现类FifoPriorityThreadPoolExecutor 先进先出的策略线程池
//先进先出的线程池策略的外围线程和最大线程的数量的是一样的public class FifoPriorityThreadPoolExecutor extends ThreadPoolExecutor { public FifoPriorityThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAlive, TimeUnit timeUnit, ThreadFactory threadFactory, UncaughtThrowableStrategy uncaughtThrowableStrategy) { super(corePoolSize, maximumPoolSize, keepAlive, timeUnit, new PriorityBlockingQueue<Runnable>(), threadFactory); this.uncaughtThrowableStrategy = uncaughtThrowableStrategy; }}
FifoPriorityThreadPoolExecutor 的对象有sourceService 和diskCacheService 2个。
和diskCacheService 的外围线程和最大线程数为1个
Glide 外面的会组装成Engine 负责EngineJob工作治理
if (engine == null) { engine = new Engine(memoryCache, diskCacheFactory, diskCacheService, sourceService); }
再由Engine 组装成Glide
return new Glide(engine, memoryCache, bitmapPool, context, decodeFormat);
六:线程池的分类
在Executors工厂类中提供了多种线程池,典型的有以下四种
- SingleThreadExecutor 单线程线程池
public static ExecutorService newSingleThreadExecutor() { return new FinalizableDelegatedExecutorService (new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>())); }//测试创立线程 public static void singleThreadPool(){ ExecutorService aa= Executors.newSingleThreadExecutor(); // 创立工作 Runnable runnable = new Runnable() { @Override public void run() { System.out.println("工作被执行,线程:" + Thread.currentThread().getName()); } }; aa.execute(runnable); }
外围线程数为1,最大线程数为1,也就是说SingleThreadExecutor这个线程池中的线程数固定为1。应用场景:当多个工作都须要拜访同一个资源的时候
- FixedThreadPool 固定容量线程池
public static ExecutorService newFixedThreadPool(int nThreads) { return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()); }//栗子:创立线程,固定的线程池 public static void fixedThreadPool(){ ExecutorService aa= newFixedThreadPool(2); // 创立工作 Runnable runnable = new Runnable() { @Override public void run() { System.out.println("工作被执行,线程:" + Thread.currentThread().getName()); } }; aa.execute(runnable); }
外围线程数为n,最大线程数为n。应用场景:明确同时执行工作数量时。
- CachedThreadPool 缓存线程池
public static ExecutorService newCachedThreadPool() { return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>()); }//栗子:缓存线程池public static void cachedThreadPool(){ ExecutorService aa= Executors.newCachedThreadPool(); // 创立工作 Runnable runnable = new Runnable() { @Override public void run() { System.out.println("工作被执行,线程:" + Thread.currentThread().getName()); } }; aa.execute(runnable); }
外围线程数为0,最大线程数无下限,线程超时工夫60秒。应用场景:解决大量耗时较短的工作。
- ScheduledThreadPool 定时线程池
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) { return new ScheduledThreadPoolExecutor(corePoolSize); } public ScheduledThreadPoolExecutor(int corePoolSize) { super(corePoolSize, Integer.MAX_VALUE, DEFAULT_KEEPALIVE_MILLIS, MILLISECONDS, new DelayedWorkQueue()); }//栗子:定时工作的创立线程池public static void scheduledThreadPool(){ ExecutorService aa= Executors.newScheduledThreadPool(1); // 创立工作 Runnable runnable = new Runnable() { @Override public void run() { System.out.println("工作被执行,线程:" + Thread.currentThread().getName()); } }; aa.execute(runnable); }
外围线程数自定,最大线程数无下限。应用场景:解决延时工作