Java中的线程池是如何运行的

  介绍

本篇文章给大家分享的是有关Java中的线程池是如何运行的,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。

异步编程工具在Android开发中目前最被推荐的就是芬兰湾的科特林协程,在引入芬兰湾的科特林协程机制前,除了响应式扩展(RxJava)兼任异步编程工具外,Java API中线程与线程池就是最重要异步编程手段。而对于Android平台的芬兰湾的科特林协程实现来说,依然使用的是线程池来作为任务执行的载体,所以可以将Android平台的芬兰湾的科特林协程简单的理解是对线程池的一种高度封装。

Executors.newFixedThreadPool (10) .asCoroutineDispatcher ()   Dispatchers.IO.asExecutor ()

因此我们先了解Java线程池是如何运行的,再深入理解芬兰湾的科特林协程是如何实现的。

<强>从线程到执行人

线程的创建通过线程类,为了复用线程而进行池化就有了线程池。线程池带来了两点明显优势:

<李>

降低重复创建线程的开销

<李>

将任务与线程管理解耦

执行人接口就是第二点的体现。其执行方法用于执行任务,不必关系这个任务执行的载体究竟是什么,到底有没有创建线程.ThreadPoolExecutor实现类就是这个任务执行器的线程池实现。

<强> ThreadPoolExecutor的任务添加与线程复用

, public  void 执行(Runnable 命令),{   if 才能;(command ==, null)   ,,throw  new  NullPointerException ();   int 才能;c =, ctl.get ();   if 才能;(workerCountOf (c), & lt;, corePoolSize), {   ,,if  (addWorker(命令,,真的)   ,,,返回;   ,,c =, ctl.get ();   }//才能1   if 才能;(正在(c),,,, workQueue.offer(命令),{   ,,int  recheck =, ctl.get ();   ,,if (!,正在(复核),,,,删除(命令)   ,,,拒绝(命令);   ,,else  if  (workerCountOf(复核),==,0)   ,,,addWorker(零,,假);   }//2才能   else 才能;if  (! addWorker(命令,,假的))   ,,拒绝(命令);//3   以前,}

查看执行方法可以清楚了解其运行方式:

<李>

当线程数小于corePoolSize时,创建线程并执行任务,

<李>

若任务未通过步骤1添加,则入队工作队列;(主要逻辑在如果的条件判断中,而如果内的逻辑处理的是在一些异常下,对入队的回滚或补充创建线程)

<李>

若任务未入队,则仍创建线程(上限为maximumPoolSize)并执行任务,失败则执行拒绝策略。

<代码>布尔addWorker (Runnable firstTask,布尔核心)就是创建线程的方法,方法中第二个参数代表以corePoolSize还是maximumPoolSize为界,方法内其余创建线程的细节逻辑不深究。但要关注一下线程的封装类工作者,addWorker方法内调用了工人内被封装线程的开始方法,执行工人的运行方法。我们将运行方法内的runWorker简化如下:

, void  runWorker (Worker  w), {   Runnable 才能;task =, w.firstTask;   时间=w.firstTask 才能;零;   while 才能;(task  !=, null  | |, (=task  getTask ()), !=, null), {   ,,task.run ();   ,,}   以前,}

可以发现,初始任务执行完后,不断通过getTask方法获取任务执行,以此来实现线程的复用,而不是只执行完一个任务就销毁了线程。

另外查看简化后的getTask方法如下:

, private  Runnable  getTask (), {   boolean 才能;timed =, allowCoreThreadTimeOut  | |, wc 祝辞,corePoolSize;   try {才能   ,,Runnable  r =, timed  ?   ,,,,workQueue.poll (keepAliveTime, TimeUnit.NANOSECONDS),:   ,,,,workQueue.take ();   ,,if  (r  !=, null)   ,,,return  r;   ,,},catch  (InterruptedException 重试),{,}   以前,}

任务是从阻塞队列工作队列中取出的,并且根据配置allowCoreThreadTimeOut与线程个数是否大于corePoolSize,来决定使用BlockingQueue的带超时时间的取任务方法调查,还是阻塞取任务方法,以实现任务列表为空时适时销毁线程还是阻塞线程。

回过头来看ThreadPoolExecutor的构造方法:

, public  ThreadPoolExecutor (int  corePoolSize,   ,,,,,,,int  maximumPoolSize,   ,,,,,,,long  keepAliveTime,   ,,,,,,,TimeUnit 单位,   ,,,,,,,BlockingQueue

Java中的线程池是如何运行的