<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>archive</title><link>https://archive-w.netlify.app/doc/base/thread/</link><description>Recent content on archive</description><generator>Hugo</generator><language>zh-CN</language><atom:link href="https://archive-w.netlify.app/doc/base/thread/index.xml" rel="self" type="application/rss+xml"/><item><title/><link>https://archive-w.netlify.app/doc/base/thread/thread-pool/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://archive-w.netlify.app/doc/base/thread/thread-pool/</guid><description>&lt;ul>
&lt;li>
&lt;h2 id="introthread-pool">
 Intro(THREAD POOL)
 &lt;a class="anchor" href="#introthread-pool">#&lt;/a>
&lt;/h2>
&lt;p class="tip">


 &lt;a href="https://github.com/openjdk/jdk/blob/jdk8-b120/jdk/src/share/classes/java/util/concurrent/ThreadPoolExecutor.java" rel="noopener" target="_blank">ThreadPoolExecutor.java&lt;/a>
&lt;br>&lt;br>线程池解决了两个不同的问题:
&lt;br>&lt;code>1).&lt;/code> 在执行大量异步任务时，由于减少了每个任务的调用开销，它们通常提供改进的性能;
&lt;br>&lt;code>2).&lt;/code> 在执行一组任务时，它们提供了一种绑定和管理资源(包括线程)的方法。每个ThreadPoolExecutor还维护一些基本统计信息，例如已完成任务的数量。
&lt;br>&lt;br>&lt;code>核心和最大线程数&lt;/code>：
&lt;br>线程池会根据&lt;code>核心线程数&lt;/code>和&lt;code>最大线程数&lt;/code>自动调节池中的线程数量。当一个任务提交的时候，如果少于核心线程数的线程正在运行，则一个新的线程被创建用来处理当前的任务请求（即使其它线程空闲）。如果运行的线程数在&lt;code>核心线程&lt;/code>和&lt;code>最大线程&lt;/code>之间，则优先队列任务，如果队列满了，就创建线程。
&lt;br>&lt;br>&lt;code>队列(BlockingQueue)&lt;/code>：
&lt;br>队列用来传输和持有提交的任务，它的使用和线程池中的线程数互相作用。有以下几点：
&lt;br>&lt;code>a).&lt;/code> 小于核心线程数的线程正在运行，则创建新线程。
&lt;br>&lt;code>b).&lt;/code> 大于核心线程数，则入队列
&lt;br>&lt;code>c).&lt;/code> 入队列不成功(满了)，但是小于最大线程数，则创建新线程。
&lt;br>&lt;code>d).&lt;/code> 其他情况(队列满了且达到最大线程数)，则拒绝执行。
&lt;br>&lt;br>对于队列的选择，一般有三种情况：
&lt;br>&lt;code>SynchronousQueue&lt;/code>：这个阻塞队列的特性是，每插入一个元素，必须消费之后才可以继续插入。而且可以支持公平和非公平选择，用于对等待的生产者和消费者线程进行排序。所以使用这种队列，如果在生产速度大于消费速度，则通过queue.offer()方法放不进去，只能创建新线程进行处理了。所以线程数可能无限增长。
&lt;br>&lt;img src="https://archive-w.netlify.app/.images/doc/base/thread/thread-pool/tp-queue-01.png" alt="" width="90%">
&lt;br>&lt;code>LinkedBlockingQueue&lt;/code>：偏无界队列（&lt;code>Integer.MAX_VALUE&lt;/code>）
&lt;br>&lt;code>ArrayBlockingQueue&lt;/code>：有边界
&lt;br>&lt;br>钩子方法：&lt;code>beforeExecute(Thread, Runnable) &lt;/code>、&lt;code>afterExecute(Runnable, Throwable)&lt;/code>
&lt;br>&lt;br>按需加载：&lt;code>prestartCoreThread(启动一个核心线程)&lt;/code>、&lt;code>prestartAllCoreThreads(启动所有核心线程)&lt;/code>&lt;/p>
&lt;ul>
&lt;li>
&lt;h3 id="属性">
 属性
 &lt;a class="anchor" href="#%e5%b1%9e%e6%80%a7">#&lt;/a>
&lt;/h3>
&lt;p class="warn">&lt;strong>ctl&lt;/strong> 是一个原子整数类型，里面主要体现两个属性：&lt;code>workerCount&lt;/code>: 有效的线程数量、&lt;code>runState&lt;/code>: 是否运行，关闭等状态。
&lt;br>为了将这两个属性放在一个数字里面控制，我们限制了&lt;code>workerCount&lt;/code>的值为 &lt;span class="math inline">\({\color{blue}(2^{29} - 1 )}\)&lt;/span>(大约5亿个线程)，而不是 &lt;span class="math inline">\({\color{blue} (2^{31} - 1)}\)&lt;/span>(大约20亿)
&lt;br>&lt;br>&lt;code>workerCount&lt;/code>：允许开始执行的线程数。因为一些原因，这个值可能和实际存活的线程数暂时不一致，比如：当要求线程池创建线程的时候失败了，或者在terminated之前退出线程依旧在执行任务。
&lt;br>&lt;br>&lt;code>runState&lt;/code>：线程池状态
&lt;br>&lt;span style='padding-left: 2.9em'/>&lt;code>RUNNING&lt;/code>: 可以接受新的任务并且处理队列中的任务
&lt;br>&lt;span style='padding-left: 2.9em'/>&lt;code>SHUTDOWN&lt;/code>: 不接受新的任务但是会处理队列中的任务
&lt;br>&lt;span style='padding-left: 2.9em'/>&lt;code>STOP&lt;/code>: 不接受新的任务，不处理队列中的任务，并且给中断正在执行的线程
&lt;br>&lt;span style='padding-left: 2.9em'/>&lt;code>TIDYING&lt;/code>: 所有任务都已种植，&lt;strong>workerCount&lt;/strong> 为零，转换到 &lt;strong>TIDYING&lt;/strong> 状态的线程将执行&lt;code>terminated()&lt;/code>钩子方法。
&lt;br>&lt;span style='padding-left: 2.9em'/>&lt;code>TERMINATED&lt;/code>: &lt;code>terminated()&lt;/code>钩子方法执行完毕。
&lt;br>&lt;br>为了允许有序比较，这些值之间的数字顺序很重要。runState单调地随时间增加，但不需要达到每个状态。转换过程：&lt;/p>
&lt;div class="alert callout attention">&lt;p class="title">&lt;span class="icon icon icon-attention">&lt;/span> Caution &lt;/p></description></item></channel></rss>