You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

1 lines
54 KiB

<!doctypehtml><html lang=zh-CN><meta charset=UTF-8><meta content=width=device-width name=viewport><meta media="(prefers-color-scheme: light)" content=#222 name=theme-color><meta media="(prefers-color-scheme: dark)" content=#222 name=theme-color><meta content="Hexo 7.3.0" name=generator><link href=https://cdnjs.cloudflare.com rel=preconnect><link href=/images/apple-touch-icon-next.png rel=apple-touch-icon sizes=180x180><link href=/images/favicon-32x32-next.png rel=icon sizes=32x32 type=image/png><link href=/images/favicon-16x16-next.png rel=icon sizes=16x16 type=image/png><link color=#222 href=/images/logo.svg rel=mask-icon><meta content=2X6S9P7CAjXjVvw8YyQR8pCu-B0oEu7O9quLgxXuWyA name=google-site-verification><meta content=dV8JGNzi0c name=baidu-site-verification><script>!function(){var t=!1;function e(){var e;t||(t=!0,(e=document.createElement("script")).setAttribute("data-ad-client","ca-pub-7480618470784058"),e.async=!0,e.src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js",document.head.appendChild(e))}function a(){"requestIdleCallback"in window?window.requestIdleCallback(e,{timeout:5e3}):window.setTimeout(e,5e3)}"complete"===document.readyState?a():window.addEventListener("load",a,{once:!0})}()</script><link href=/css/main.css rel=stylesheet><link crossorigin=anonymous href=https://cdnjs.cloudflare.com/ajax/libs/font-awesome/7.0.0/css/all.min.css integrity=sha256-VHqXKFhhMxcpubYf9xiWdCiojEbY9NexQ4jh8AxbvcM= rel=stylesheet><link crossorigin=anonymous href=https://cdnjs.cloudflare.com/ajax/libs/fancyapps-ui/6.1.14/fancybox/fancybox.css integrity=sha256-mdaMxrItEW6hMIVJJNPKuX0B7KCSJQVEv3mVY4N2we4= rel=stylesheet><script class=next-config data-name=main type=application/json>{"hostname":"nicksxs.me","root":"/","images":"/images","scheme":"Pisces","darkmode":true,"version":"8.29.0","exturl":false,"sidebar":{"position":"left","width_expanded":320,"width_dual_column":240,"display":"post","padding":18,"offset":12},"hljswrap":true,"codeblock":{"theme":{"light":"default","dark":"stackoverflow-dark"},"prism":{"light":"prism","dark":"prism-dark"},"copy_button":{"enable":true,"style":"default"},"fold":{"enable":false,"height":500},"language":false},"bookmark":{"enable":false,"color":"#222","save":"auto"},"mediumzoom":false,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":true,"nav":null},"stickytabs":false,"motion":{"enable":false,"async":false,"duration":200,"transition":{"menu_item":"fadeInDown","post_block":"fadeIn","post_header":"fadeInDown","post_body":"fadeInDown","coll_header":"fadeInLeft","sidebar":"fadeInUp"}},"prism":false,"i18n":{"placeholder":"搜索...","empty":"没有找到任何搜索结果:${query}","hits_time":"找到 ${hits} 个搜索结果(用时 ${time} 毫秒)","hits":"找到 ${hits} 个搜索结果"},"algolia":{"appID":"663Q99OQQD","apiKey":"e461a1371d12cec1491c1153b288a9ed","indexName":"nicksxs","hits":{"per_page":10}}}</script><script defer src=/js/config.js></script><meta content="这一篇我们继续聊线程池,一般线程池会介绍我们的参数,我先不一样一些 我们先来翻译一下 通过前面的简单翻译我们就能大致略窥得线程池配置全貌,继续看一个构造方法 这个构造方法就主要配置了 corePoolSize 核心线程数,maximumPoolSize 最大线程数, keepA…" name=description><meta content=article property=og:type><meta content="Java 线程池系列-第一篇" property=og:title><meta content=https://nicksxs.me/2024/02/11/Java-%E7%BA%BF%E7%A8%8B%E6%B1%A0%E7%B3%BB%E5%88%97-%E7%AC%AC%E4%B8%80%E7%AF%87/index.html property=og:url><meta content="Nicksxs's Blog" property=og:site_name><meta content="这一篇我们继续聊线程池,一般线程池会介绍我们的参数,我先不一样一些 我们先来翻译一下 通过前面的简单翻译我们就能大致略窥得线程池配置全貌,继续看一个构造方法 这个构造方法就主要配置了 corePoolSize 核心线程数,maximumPoolSize 最大线程数, keepA…" property=og:description><meta content=zh_CN property=og:locale><meta content=2024-02-11T11:39:05.000Z property=article:published_time><meta content=2024-02-11T11:39:05.000Z property=article:modified_time><meta content=Nicksxs property=article:author><meta content=Java property=article:tag><meta content=summary name=twitter:card><link href=https://nicksxs.me/2024/02/11/Java-%E7%BA%BF%E7%A8%8B%E6%B1%A0%E7%B3%BB%E5%88%97-%E7%AC%AC%E4%B8%80%E7%AF%87/ rel=canonical><script class=next-config data-name=page type=application/json>{"sidebar":"","isHome":false,"isPost":true,"lang":"zh-CN","comments":true,"permalink":"https://nicksxs.me/2024/02/11/Java-%E7%BA%BF%E7%A8%8B%E6%B1%A0%E7%B3%BB%E5%88%97-%E7%AC%AC%E4%B8%80%E7%AF%87/","path":"2024/02/11/Java-线程池系列-第一篇/","title":"Java 线程池系列-第一篇"}</script><script class=next-config data-name=calendar type=application/json>""</script><title>Java 线程池系列-第一篇 | Nicksxs's Blog</title><script async src=https://www.googletagmanager.com/gtag/js?id=UA-61358619-1></script><script class=next-config data-name=google_analytics type=application/json>{"tracking_id":"UA-61358619-1","only_pageview":false,"measure_protocol_api_secret":null}</script><script defer src=/js/third-party/analytics/google-analytics.js></script><script defer src=/js/third-party/analytics/baidu-analytics.js></script><script async src=https://hm.baidu.com/hm.js?20f33b3c0c0eff9b1522999c0015646d></script><script crossorigin=anonymous defer integrity=sha256-QnJV4HT5r8i89ovZGRD86iynZqHerEbT2xt69vDM36I= src=https://cdnjs.cloudflare.com/ajax/libs/fancyapps-ui/6.1.14/fancybox/fancybox.umd.js></script><script defer src=/js/utils.js></script><script defer src=/js/sidebar.js></script><script defer src=/js/next-boot.js></script><script data-algolia-integrity=sha256-o49zoHLDPBm9WLg6AiliAVi3axCRTqe3ltTxLvhzAVg= data-algolia-src=https://cdnjs.cloudflare.com/ajax/libs/algoliasearch/5.36.0/lite/builds/browser.umd.js data-search-src=/js/third-party/search/algolia-search.js src=/js/third-party/search/algolia-search-loader.js></script><script defer src=/js/third-party/fancybox.js></script><noscript><link href=/css/noscript.css rel=stylesheet></noscript><link title="Nicksxs's Blog" href=/atom.xml rel=alternate type=application/atom+xml><body itemscope itemtype=http://schema.org/WebPage><div class=headband></div><main class=main><div class=column><header class=header itemscope itemtype=http://schema.org/WPHeader><div class=site-brand-container><div class=site-nav-toggle><div aria-label=切换导航栏 class=toggle role=button><span class=toggle-line></span><span class=toggle-line></span><span class=toggle-line></span></div></div><div class=site-meta><a class=brand href=/ rel=start><i class=logo-line></i><p class=site-title>Nicksxs's Blog</p><i class=logo-line></i></a><p class=site-subtitle itemprop=description>Java 运行时、生产诊断与 AI 工程实践</div><div class=site-nav-right><div class="toggle popup-trigger" aria-label=搜索 role=button><i class="fa fa-search fa-fw fa-lg"></i></div></div></div><nav class=site-nav><ul class="main-menu menu"><li class="menu-item menu-item-home"><a href=/ rel=section><i class="fa fa-home fa-fw"></i>首页</a><li class="menu-item menu-item-专题"><a href=/topics/ rel=section><i class="fa fa-layer-group fa-fw"></i>专题</a><li class="menu-item menu-item-工具"><a href=/tools/ rel=section><i class="fa fa-toolbox fa-fw"></i>工具</a><li class="menu-item menu-item-about"><a href=/about/ rel=section><i class="fa fa-user fa-fw"></i>关于我</a><li class="menu-item menu-item-tags"><a href=/tags/ rel=section><i class="fa fa-tags fa-fw"></i>标签</a><li class="menu-item menu-item-categories"><a href=/categories/ rel=section><i class="fa fa-th fa-fw"></i>分类</a><li class="menu-item menu-item-archives"><a href=/archives/ rel=section><i class="fa fa-archive fa-fw"></i>归档</a><li class="menu-item menu-item-search"><a class=popup-trigger role=button><i class="fa fa-search fa-fw"></i>搜索</a></ul></nav><div class=search-pop-overlay><div class="popup search-popup"><div class=search-header><span class=search-icon><i class="fa fa-search"></i></span><div class=search-input-container><input autocapitalize=off autocomplete=off class=search-input maxlength=80 placeholder=搜索... spellcheck=false type=search></div><span class=popup-btn-close role=button><i class="fa fa-times-circle"></i></span></div><div class=search-result-container><div class=search-result-icon><i class="fab fa-algolia fa-5x"></i></div></div></div></div></header><aside class=sidebar><div class="sidebar-inner sidebar-overview-active"><ul class=sidebar-nav><li class=sidebar-nav-toc>文章目录<li class=sidebar-nav-overview>站点概览</ul><div class=sidebar-panel-container><div class="post-toc-wrap sidebar-panel"></div><div class="site-overview-wrap sidebar-panel"><div class="site-author animated" itemprop=author itemscope itemtype=http://schema.org/Person><img alt=Nicksxs class=site-author-image itemprop=image src=/uploads/avatar.jpg><p class=site-author-name itemprop=name>Nicksxs<div class=site-description itemprop=description>Nicksxs 的技术博客,深入 Java 运行时与生产诊断、低成本大模型推理和 Agent 工程实践。</div></div><div class="site-state-wrap animated"><nav class=site-state><div class="site-state-item site-state-posts"><a href=/archives/><span class=site-state-item-count>394</span> <span class=site-state-item-name>日志</span></a></div><div class="site-state-item site-state-categories"><a href=/categories/><span class=site-state-item-count>181</span> <span class=site-state-item-name>分类</span></a></div><div class="site-state-item site-state-tags"><a href=/tags/><span class=site-state-item-count>347</span> <span class=site-state-item-name>标签</span></a></div></nav></div><div class="links-of-author animated"><span class=links-of-author-item><a rel="noopener me" title="GitHub → https://github.com/nicksxs" href=https://github.com/nicksxs target=_blank><i class="fab fa-github fa-fw"></i>GitHub</a> </span><span class=links-of-author-item><a rel="noopener me" title="E-Mail → mailto:nicksxs1202@gmail.com" href=mailto:nicksxs1202@gmail.com target=_blank><i class="fa fa-envelope fa-fw"></i>E-Mail</a></span></div><div class="cc-license animated" itemprop=license><a class=cc-opacity href=https://creativecommons.org/licenses/by-nc-sa/4.0/ rel=noopener target=_blank><img alt="Creative Commons" src=https://cdnjs.cloudflare.com/ajax/libs/creativecommons-vocabulary/2020.11.3/assets/license_badges/small/by_nc_sa.svg></a></div><div class="widget-wrap sidebar-tag-cloud"><div class=tag-cloud-tags><a class=tag-cloud-10 href=/tags/Java/ style=font-size:16px>Java</a><a class=tag-cloud-9 href=/tags/leetcode/ style=font-size:15.62px>leetcode</a><a class=tag-cloud-8 href=/tags/LLM/ style=font-size:15.23px>LLM</a><a class=tag-cloud-8 href=/tags/%E7%94%9F%E6%B4%BB/ style=font-size:14.85px>生活</a><a class=tag-cloud-7 href=/tags/%E9%A2%98%E8%A7%A3/ style=font-size:14.46px>题解</a><a class=tag-cloud-6 href=/tags/SpringBoot/ style=font-size:14.08px>SpringBoot</a><a class=tag-cloud-6 href=/tags/MySQL/ style=font-size:14.08px>MySQL</a><a class=tag-cloud-5 href=/tags/C/ style=font-size:13.69px>C++</a><a class=tag-cloud-5 href=/tags/Redis/ style=font-size:13.31px>Redis</a><a class=tag-cloud-4 href=/tags/Tomcat/ style=font-size:12.92px>Tomcat</a><a class=tag-cloud-4 href=/tags/Mybatis/ style=font-size:12.92px>Mybatis</a><a class=tag-cloud-3 href=/tags/%E5%B0%8F%E6%8A%80%E5%B7%A7/ style=font-size:12.54px>小技巧</a><a class=tag-cloud-2 href=/tags/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/ style=font-size:12.15px>数据结构</a><a class=tag-cloud-2 href=/tags/%E6%BA%90%E7%A0%81/ style=font-size:12.15px>源码</a><a class=tag-cloud-2 href=/tags/MQ/ style=font-size:11.77px>MQ</a><a class=tag-cloud-2 href=/tags/%E6%B6%88%E6%81%AF%E9%98%9F%E5%88%97/ style=font-size:11.77px>消息队列</a><a class=tag-cloud-2 href=/tags/RocketMQ/ style=font-size:11.77px>RocketMQ</a><a class=tag-cloud-2 href=/tags/%E8%BF%90%E5%8A%A8/ style=font-size:11.77px>运动</a><a class=tag-cloud-1 href=/tags/php/ style=font-size:11.38px>php</a><a class=tag-cloud-0 href=/tags/Spring/ style=font-size:11px>Spring</a><a class=tag-cloud-0 href=/tags/linux/ style=font-size:11px>linux</a><a class=tag-cloud-0 href=/tags/Docker/ style=font-size:11px>Docker</a><a class=tag-cloud-0 href=/tags/%E5%87%8F%E8%82%A5/ style=font-size:11px>减肥</a><a class=tag-cloud-0 href=/tags/%E8%B7%91%E6%AD%A5/ style=font-size:11px>跑步</a></div></div><div class="affiliate-creative affiliate-creative--sidebar" data-affiliate-id=tencent-cloud-general><a rel="sponsored noopener" aria-label=腾讯云产品优惠 href=https://cloud.tencent.com/act/cps/redirect?redirect=2446&cps_key=2e33a1eedb380997d03618b4a5ba6ca7&from=console target=_blank><img alt=腾讯云服务器、数据库和云产品优惠 decoding=async height=419 loading=lazy src=/uploads/affiliate/tencent-cloud-general.webp width=690> </a><span class=affiliate-disclosure>推广</span></div></div></div></div><div class="sidebar-inner sidebar-blogroll"><div class="links-of-blogroll animated"><div class=links-of-blogroll-title><i class="fa fa-globe fa-fw"></i> 链接</div><ul class=links-of-blogroll-list><li class=links-of-blogroll-item><a href=https://covermusic.cn/ rel=noopener target=_blank title=https://covermusic.cn>69伙伴</a></ul></div></div></aside></div><div class="main-inner post posts-expand"><div class=post-block><article class=post-content itemscope itemtype=http://schema.org/Article lang=zh-CN><link href=https://nicksxs.me/2024/02/11/Java-%E7%BA%BF%E7%A8%8B%E6%B1%A0%E7%B3%BB%E5%88%97-%E7%AC%AC%E4%B8%80%E7%AF%87/ itemprop=mainEntityOfPage><span hidden itemprop=author itemscope itemtype=http://schema.org/Person><meta content=/uploads/avatar.jpg itemprop=image><meta content=Nicksxs itemprop=name></span><span hidden itemprop=publisher itemscope itemtype=http://schema.org/Organization><meta content="Nicksxs's Blog" itemprop=name><meta content="Nicksxs 的技术博客,深入 Java 运行时与生产诊断、低成本大模型推理和 Agent 工程实践。" itemprop=description></span><span hidden itemprop=post itemscope itemtype=http://schema.org/CreativeWork><meta content="Java 线程池系列-第一篇 | Nicksxs's Blog" itemprop=name><meta content="这一篇我们继续聊线程池,一般线程池会介绍我们的参数,我先不一样一些 我们先来翻译一下 通过前面的简单翻译我们就能大致略窥得线程池配置全貌,继续看一个构造方法 这个构造方法就主要配置了 corePoolSize 核心线程数,maximumPoolSize 最大线程数, keepA…" itemprop=description></span><header class=post-header><h1 itemprop="name headline" class=post-title>Java 线程池系列-第一篇</h1><div class=post-meta-container><div class=post-meta><span class=post-meta-item><span class=post-meta-item-icon><i class="far fa-calendar"></i> </span><span class=post-meta-item-text>发表于</span> <time itemprop="dateCreated datePublished" title="创建时间:2024-02-11 19:39:05" datetime=2024-02-11T19:39:05+08:00>2024-02-11</time> </span><span class=post-meta-item><span class=post-meta-item-icon><i class="far fa-folder"></i> </span><span class=post-meta-item-text>分类于</span> <span itemprop=about itemscope itemtype=http://schema.org/Thing><a href=/categories/Java/ itemprop=url rel=index><span itemprop=name>Java</span></a> </span></span><span class="post-meta-item cloudflare-page-counter" data-title="Java 线程池系列-第一篇" data-increment=true data-path=/2024/02/11/Java-%E7%BA%BF%E7%A8%8B%E6%B1%A0%E7%B3%BB%E5%88%97-%E7%AC%AC%E4%B8%80%E7%AF%87/ title=阅读次数><span class=post-meta-item-icon><i class="far fa-eye"></i> </span><span class=post-meta-item-text>阅读次数:</span> <span class=cloudflare-page-counter-count></span></span></div><div class=post-description>这一篇我们继续聊线程池,一般线程池会介绍我们的参数,我先不一样一些 我们先来翻译一下 通过前面的简单翻译我们就能大致略窥得线程池配置全貌,继续看一个构造方法 这个构造方法就主要配置了 corePoolSize 核心线程数,maximumPoolSize 最大线程数, keepA…</div></div></header><div class=post-body itemprop=articleBody><p>这一篇我们继续聊线程池,一般线程池会介绍我们的参数,我先不一样一些<br>我们先来翻译一下<figure class="highlight java"><table><tr><td class=gutter><pre><span class=line>1</span><br><span class=line>2</span><br><span class=line>3</span><br><span class=line>4</span><br><span class=line>5</span><br><span class=line>6</span><br><span class=line>7</span><br><span class=line>8</span><br><span class=line>9</span><br><span class=line>10</span><br><span class=line>11</span><br><span class=line>12</span><br><span class=line>13</span><br><span class=line>14</span><br><span class=line>15</span><br><span class=line>16</span><br><span class=line>17</span><br><span class=line>18</span><br><span class=line>19</span><br><span class=line>20</span><br><span class=line>21</span><br><span class=line>22</span><br><span class=line>23</span><br><span class=line>24</span><br><span class=line>25</span><br><span class=line>26</span><br><span class=line>27</span><br><span class=line>28</span><br><span class=line>29</span><br><span class=line>30</span><br><span class=line>31</span><br><span class=line>32</span><br><span class=line>33</span><br><span class=line>34</span><br><span class=line>35</span><br><span class=line>36</span><br><span class=line>37</span><br><span class=line>38</span><br><span class=line>39</span><br><span class=line>40</span><br><span class=line>41</span><br><span class=line>42</span><br><span class=line>43</span><br><span class=line>44</span><br><span class=line>45</span><br><span class=line>46</span><br><span class=line>47</span><br><span class=line>48</span><br><span class=line>49</span><br><span class=line>50</span><br><span class=line>51</span><br><span class=line>52</span><br><span class=line>53</span><br><span class=line>54</span><br><span class=line>55</span><br><span class=line>56</span><br><span class=line>57</span><br><span class=line>58</span><br><span class=line>59</span><br><span class=line>60</span><br><span class=line>61</span><br><span class=line>62</span><br><span class=line>63</span><br><span class=line>64</span><br><span class=line>65</span><br><span class=line>66</span><br><span class=line>67</span><br><span class=line>68</span><br><span class=line>69</span><br><span class=line>70</span><br><span class=line>71</span><br><span class=line>72</span><br><span class=line>73</span><br><span class=line>74</span><br><span class=line>75</span><br><span class=line>76</span><br><span class=line>77</span><br><span class=line>78</span><br><span class=line>79</span><br><span class=line>80</span><br><span class=line>81</span><br><span class=line>82</span><br><span class=line>83</span><br><span class=line>84</span><br><span class=line>85</span><br><span class=line>86</span><br><span class=line>87</span><br><span class=line>88</span><br><span class=line>89</span><br><span class=line>90</span><br><span class=line>91</span><br><span class=line>92</span><br><span class=line>93</span><br><span class=line>94</span><br><span class=line>95</span><br></pre><td class=code><pre><span class=line> An {<span class=meta>@link</span> ExecutorService} that executes each submitted task using</span><br><span class=line> one of possibly several pooled threads, normally configured</span><br><span class=line> using {<span class=meta>@link</span> Executors} factory methods.</span><br><span class=line> <span class=comment>// executorService 使用一个线程池中的线程来执行每个提交的任务,经常使用 Executors 工厂方法</span></span><br><span class=line></span><br><span class=line> &LTp>Thread pools address two different problems: they usually</span><br><span class=line> provide improved performance when executing large numbers of</span><br><span class=line> asynchronous tasks, due to reduced per-task invocation overhead,</span><br><span class=line> and they provide a means of bounding and managing the resources,</span><br><span class=line> including threads, consumed when executing a collection of tasks.</span><br><span class=line> Each {<span class=meta>@code</span> ThreadPoolExecutor} also maintains some basic</span><br><span class=line> statistics, such as the number of completed tasks.</span><br><span class=line> <span class=comment>// 线程池解决两个不同的问题,通常是为了在提交大量异步任务时,通过减少每个任务的调度开销来提高性能</span></span><br><span class=line> <span class=comment>// 并且提供了一种管理和约束资源,包括线程消耗的方法,每个 ThreadPoolExecutor还会管理一些基础的统计信息</span></span><br><span class=line> <span class=comment>// 比如完成的任务数量</span></span><br><span class=line> </span><br><span class=line></span><br><span class=line> &LTp>To be useful across a wide range of contexts, <span class=built_in>this</span> <span class=keyword>class</span></span><br><span class=line> <span class="title class_">provides</span> many adjustable parameters and extensibility</span><br><span class=line> hooks. However, programmers are urged to use the more convenient</span><br><span class=line> {<span class=meta>@link</span> Executors} factory methods {<span class=meta>@link</span></span><br><span class=line> Executors#newCachedThreadPool} (unbounded thread pool, with</span><br><span class=line> automatic thread reclamation), {<span class=meta>@link</span> Executors#newFixedThreadPool}</span><br><span class=line> (fixed size thread pool) and {<span class=meta>@link</span></span><br><span class=line> Executors#newSingleThreadExecutor} (single background thread), that</span><br><span class=line> preconfigure settings <span class=keyword>for</span> the most common usage</span><br><span class=line> scenarios. Otherwise, use the following guide when manually</span><br><span class=line> configuring and tuning <span class=built_in>this</span> class:</span><br><span class=line> <span class=comment>// 为了在各种情况下都能派上用场,该类提供了许多可调整的参数和扩展钩子。不过,我们建议程序员使用更方便的 Executors 工厂方法 Executors.</span></span><br><span class=line> <span class=comment>// newCachedThreadPool(无限制线程池,可自动回收线程)、Executors.newFixedThreadPool(固定大小线程池)和 Executors.</span></span><br><span class=line> <span class=comment>// newSingleThreadExecutor(单后台线程),这些方法可为最常见的使用场景预先配置设置。否则,在手动配置和调整该类时,请使用以下指南:</span></span><br><span class=line></span><br><span class=line> Core and maximum pool sizes</span><br><span class=line> <span class=comment>// 核心和最大线程池大小</span></span><br><span class=line> A ThreadPoolExecutor will automatically adjust the pool <span class="title function_">size</span> <span class=params>(see getPoolSize)</span> according to the bounds set by <span class="title function_">corePoolSize</span> <span class=params>(see getCorePoolSize)</span> and <span class="title function_">maximumPoolSize</span> <span class=params>(see getMaximumPoolSize)</span>. When a <span class=keyword>new</span> <span class="title class_">task</span> is submitted in method <span class="title function_">execute</span><span class=params>(Runnable)</span>, and fewer than corePoolSize threads are running, a <span class=keyword>new</span> <span class="title class_">thread</span> is created to handle the request, even <span class=keyword>if</span> other worker threads are idle. If there are more than corePoolSize but less than maximumPoolSize threads running, a <span class=keyword>new</span> <span class="title class_">thread</span> will be created only <span class=keyword>if</span> the queue is full. By setting corePoolSize and maximumPoolSize the same, you create a fixed-size thread pool. By setting maximumPoolSize to an essentially unbounded value such as Integer.MAX_VALUE, you allow the pool to accommodate an arbitrary number of concurrent tasks. Most typically, core and maximum pool sizes are set only upon construction, but they may also be changed dynamically using setCorePoolSize and setMaximumPoolSize.</span><br><span class=line> <span class=comment>// ThreadPoolExecutor 会根据 corePoolSize(参见 getCorePoolSize)和 maximumPoolSize(参见 getMaximumPoolSize)设置的界限自动调整池大小(参见 getPoolSize)。在方法 execute(Runnable) 中提交新任务时,如果运行的线程少于 corePoolSize,即使其他工作线程处于空闲状态,也会创建一个新线程来处理请求。如果运行的线程多于 corePoolSize 但少于 maximumPoolSize,则只有在队列已满时才会创建新线程。如果将 corePoolSize 和 maximumPoolSize 设置为相同,就可以创建一个固定大小的线程池。如果将 maximumPoolSize 设置为 Integer.MAX_VALUE 等基本无限制的值,就可以让池容纳任意数量的并发任务。通常,核心和最大线程池大小只在构建时设置,但也可以使用 setCorePoolSize 和 setMaximumPoolSize 动态更改。</span></span><br><span class=line></span><br><span class=line>On-demand construction</span><br><span class=line><span class=comment>// 按需构建</span></span><br><span class=line> By <span class=keyword>default</span>, even core threads are initially created and started only when <span class=keyword>new</span> <span class="title class_">tasks</span> arrive, but <span class=built_in>this</span> can be overridden dynamically using method prestartCoreThread or prestartAllCoreThreads. You probably want to prestart threads <span class=keyword>if</span> you construct the pool with a non-empty queue.</span><br><span class=line> <span class=comment>// 默认情况下,即使是核心线程也是只有当新任务到来时才会初始创建和启动,但这可以使用方法 prestartCoreThread 或 prestartAllCoreThreads 进行动态重载。如果使用非空队列构建线程池,则可能需要预启动线程。</span></span><br><span class=line>Creating <span class=keyword>new</span> <span class="title class_">threads</span></span><br><span class=line><span class=comment>// 创建新线程</span></span><br><span class=line> <span class=comment>/** New threads are created using a ThreadFactory. If not otherwise specified, a Executors.defaultThreadFactory is used, that creates threads to all be in the same ThreadGroup and with the same NORM_PRIORITY priority and non-daemon status. By supplying a different ThreadFactory, you can alter the thread's name, thread group, priority, daemon status, etc. If a ThreadFactory fails to create a thread when asked by returning null from newThread, the executor will continue, but might not be able to execute any tasks. Threads should possess the "modifyThread" RuntimePermission. If worker threads or other threads using the pool do not possess this permission, service may be degraded: configuration changes may not take effect in a timely manner, and a shutdown pool may remain in a state in which termination is possible but not completed. */</span></span><br><span class=line> <span class=comment>// 新线程是使用线程工厂(ThreadFactory)创建的。如果未另行指定,将使用 Executors.defaultThreadFactory 创建线程,创建的线程将全部位于同一线程组,并具有相同的 NORM_PRIORITY 优先级和非守护进程状态。通过提供不同的 ThreadFactory,可以更改线程的名称、线程组、优先级、守护进程状态等。如果线程工厂无法按要求创建线程,从 newThread 返回空值,执行器将继续运行,但可能无法执行任何任务。线程应拥有 "modifyThread "运行时权限。如果工作线程或使用池的其他线程不具备此权限,服务可能会降级:配置更改可能无法及时生效,关闭的池可能会一直处于可以终止但无法完成的状态。</span></span><br><span class=line>Keep-alive times</span><br><span class=line><span class=comment>// 保活时间</span></span><br><span class=line> If the pool currently has more than corePoolSize threads, excess threads will be terminated <span class=keyword>if</span> they have been idle <span class=keyword>for</span> more than the <span class="title function_">keepAliveTime</span> <span class=params>(see getKeepAliveTime(TimeUnit)</span>). This provides a means of reducing resource consumption when the pool is not being actively used. If the pool becomes more active later, <span class=keyword>new</span> <span class="title class_">threads</span> will be constructed. This parameter can also be changed dynamically using method <span class="title function_">setKeepAliveTime</span><span class=params>(<span class=type>long</span>, TimeUnit)</span>. Using a value of Long.MAX_VALUE TimeUnit.NANOSECONDS effectively disables idle threads from ever terminating prior to shut down. By <span class=keyword>default</span>, the keep-alive policy applies only when there are more than corePoolSize threads. But method <span class="title function_">allowCoreThreadTimeOut</span><span class=params>(<span class=type>boolean</span>)</span> can be used to apply <span class=built_in>this</span> time-out policy to core threads as well, so <span class=type>long</span> as the keepAliveTime value is non-zero.</span><br><span class=line> <span class=comment>// 如果当前池中的线程数超过 corePoolSize,多余的线程在闲置时间超过 keepAliveTime(请参阅 getKeepAliveTime(TimeUnit))时将被终止。这提供了一种在线程池未被频繁使用时减少资源消耗的方法。如果以后池变得更加活跃,就会构建新线程。也可以使用方法 setKeepAliveTime(long, TimeUnit) 动态更改该参数。使用 Long.MAX_VALUE TimeUnit.NANOSECONDS 值可有效禁止闲置线程在关闭前终止。默认情况下,只有当线程数超过 corePoolSize 时,才会采用保持连接策略。但只要 keepAliveTime 值不为零,就可以使用方法 allowCoreThreadTimeOut(boolean) 将超时策略也应用到核心线程。</span></span><br><span class=line>Queuing</span><br><span class=line><span class=comment>// 队列</span></span><br><span class=line> Any BlockingQueue may be used to transfer and hold submitted tasks. The use of <span class=built_in>this</span> queue interacts with pool sizing:</span><br><span class=line> <span class=comment>// 任何阻塞队列(BlockingQueue)都可用于传输和保留已提交的任务。该队列的使用与线程池大小有关:</span></span><br><span class=line> If fewer than corePoolSize threads are running, the Executor always prefers adding a <span class=keyword>new</span> <span class="title class_">thread</span> rather than queuing.</span><br><span class=line> <span class=comment>// 如果运行的线程少于 corePoolSize,执行器总是倾向于添加新线程而不是队列。</span></span><br><span class=line> If corePoolSize or more threads are running, the Executor always prefers queuing a request rather than adding a <span class=keyword>new</span> <span class="title class_">thread</span>.</span><br><span class=line> <span class=comment>// 如果运行的线程数大于或等于 corePoolSize,执行器总是倾向于将请求排队,而不是添加新线程。</span></span><br><span class=line> If a request cannot be queued, a <span class=keyword>new</span> <span class="title class_">thread</span> is created unless <span class=built_in>this</span> would exceed maximumPoolSize, in which <span class=keyword>case</span>, the task will be rejected.</span><br><span class=line> <span class=comment>// 如果请求无法进队列,执行器会创建一个新线程,除非这样做会超过最大线程池大小(maximumPoolSize),在这种情况下,任务会被拒绝。</span></span><br><span class=line> There are three general strategies <span class=keyword>for</span> queuing:</span><br><span class=line> <span class=comment>// 入队一般有三种策略:</span></span><br><span class=line> Direct handoffs. A good <span class=keyword>default</span> choice <span class=keyword>for</span> a work queue is a SynchronousQueue that hands off tasks to threads without otherwise holding them. Here, an attempt to queue a task will fail <span class=keyword>if</span> no threads are immediately available to run it, so a <span class=keyword>new</span> <span class="title class_">thread</span> will be constructed. This policy avoids lockups when handling sets of requests that might have internal dependencies. Direct handoffs generally require unbounded maximumPoolSizes to avoid rejection of <span class=keyword>new</span> <span class="title class_">submitted</span> tasks. This in turn admits the possibility of unbounded thread growth when commands <span class=keyword>continue</span> to arrive on average faster than they can be processed.</span><br><span class=line> <span class=comment>// 直接交接。工作队列的一个很好的默认选择是同步队列(SynchronousQueue),它可以将任务移交给线程,而不会以其他方式保留任务。在这里,如果没有线程可立即运行任务,则队列任务的尝试将失败,因此会构建一个新的线程。在处理可能存在内部依赖关系的请求集时,这种策略可以避免死锁。直接交接通常需要无限制的最大线程池大小,以避免新提交的任务被拒绝。反过来,当命令的平均到达速度超过其处理速度时,就有可能导致线程无限制增长。</span></span><br><span class=line> <span class=comment>/** Unbounded queues. Using an unbounded queue (for example a LinkedBlockingQueue without a predefined capacity) will cause new tasks to wait in the queue when all corePoolSize threads are busy. Thus, no more than corePoolSize threads will ever be created. (And the value of the maximumPoolSize therefore doesn't have any effect.) This may be appropriate when each task is completely independent of others, so tasks cannot affect each others execution; for example, in a web page server. While this style of queuing can be useful in smoothing out transient bursts of requests, it admits the possibility of unbounded work queue growth when commands continue to arrive on average faster than they can be processed. */</span></span><br><span class=line> <span class=comment>// 无界队列。使用无界队列(例如没有预定义容量的 LinkedBlockingQueue)会导致新任务在所有 corePoolSize 线程都繁忙时在队列中等待。因此,创建的线程不会超过 corePoolSize。(当每个任务都完全独立于其他任务,因此任务之间不会相互影响执行时,例如在网页服务器中,这种方式可能比较合适。虽然这种队列方式在平滑瞬时突发请求方面很有用,但当命令的平均到达速度持续超过其处理速度时,就会导致工作队列无限制地增长。</span></span><br><span class=line> Bounded queues. A bounded <span class="title function_">queue</span> <span class=params>(<span class=keyword>for</span> example, an ArrayBlockingQueue)</span> helps prevent resource exhaustion when used with finite maximumPoolSizes, but can be more difficult to tune and control. Queue sizes and maximum pool sizes may be traded off <span class=keyword>for</span> each other: Using large queues and small pools minimizes CPU usage, OS resources, and context-switching overhead, but can lead to artificially low throughput. If tasks frequently <span class="title function_">block</span> <span class=params>(<span class=keyword>for</span> example <span class=keyword>if</span> they are I/O bound)</span>, a system may be able to schedule time <span class=keyword>for</span> more threads than you otherwise allow. Use of small queues generally <span class=keyword>requires</span> larger pool sizes, which keeps CPUs busier but may encounter unacceptable scheduling overhead, which also decreases throughput.</span><br><span class=line> <span class=comment>// 有界队列 有界队列(例如 ArrayBlockingQueue)与有限的最大线程池大小一起使用时,有助于防止资源耗尽,但可能更难调整和控制。队列大小和最大池大小可以相互权衡: 使用大队列和小池可以最大限度地减少 CPU 占用率、操作系统资源和上下文切换开销,但会导致人为的低吞吐量。如果任务经常出现阻塞(例如,如果任务受 I/O 约束),系统可能会为更多线程安排时间,而不考虑其他因素。使用小队列通常需要更大的池规模,这将使 CPU 更繁忙,但可能会遇到无法接受的调度开销,这也会降低吞吐量。</span></span><br><span class=line>Rejected tasks</span><br><span class=line><span class=comment>// 被拒绝的任务</span></span><br><span class=line> New tasks submitted in method <span class="title function_">execute</span><span class=params>(Runnable)</span> will be rejected when the Executor has been shut down, and also when the Executor uses finite bounds <span class=keyword>for</span> both maximum threads and work queue capacity, and is saturated. In either <span class=keyword>case</span>, the execute method invokes the RejectedExecutionHandler.rejectedExecution(Runnable, ThreadPoolExecutor) method of its RejectedExecutionHandler. Four predefined handler policies are provided:</span><br><span class=line> <span class=comment>// 如果执行器已关闭,或者执行器使用了最大线程数和工作队列容量的有限界限,并已达到饱和,那么在 execute(Runnable) 方法中提交的新任务将被拒绝。在这两种情况下,execute 方法都会调用其 RejectedExecutionHandler 的 RejectedExecutionHandler.rejectedExecution(Runnable, ThreadPoolExecutor) 方法。提供了四种预定义的处理程序策略:</span></span><br><span class=line> In the <span class=keyword>default</span> ThreadPoolExecutor.AbortPolicy, the handler <span class=keyword>throws</span> a runtime RejectedExecutionException upon rejection.</span><br><span class=line> <span class=comment>// 在默认的 ThreadPoolExecutor.AbortPolicy 中,处理程序会在拒绝时抛出运行时 RejectedExecutionException。</span></span><br><span class=line> In ThreadPoolExecutor.CallerRunsPolicy, the thread that invokes execute itself runs the task. This provides a simple feedback control mechanism that will slow down the rate that <span class=keyword>new</span> <span class="title class_">tasks</span> are submitted.</span><br><span class=line> <span class=comment>// 在 ThreadPoolExecutor.CallerRunsPolicy 中,调用执行本身的线程会运行任务。这提供了一个简单的反馈控制机制,可减慢提交新任务的速度。</span></span><br><span class=line> In ThreadPoolExecutor.DiscardPolicy, a task that cannot be executed is simply dropped.</span><br><span class=line> <span class=comment>// 在 ThreadPoolExecutor.DiscardPolicy 中,无法执行的任务会被直接丢弃。</span></span><br><span class=line> In ThreadPoolExecutor.DiscardOldestPolicy, <span class=keyword>if</span> the executor is not shut down, the task at the head of the work queue is dropped, and then execution is <span class="title function_">retried</span> <span class=params>(which can fail again, causing <span class=built_in>this</span> to be repeated.)</span></span><br><span class=line> <span class=comment>// 在 ThreadPoolExecutor.DiscardOldestPolicy 中,如果执行器没有关闭,工作队列头部的任务就会被丢弃,然后重新执行(可能会再次失败,导致重复执行)。</span></span><br><span class=line> It is possible to define and use other kinds of RejectedExecutionHandler classes. Doing so <span class=keyword>requires</span> some care especially when policies are designed to work only under particular capacity or queuing policies.</span><br><span class=line> <span class=comment>// 我们还可以定义和使用其他类型的 RejectedExecutionHandler 类。这样做需要小心谨慎,尤其是当策略设计为仅在特定容量或队列策略下运行时。</span></span><br><span class=line>Hook methods</span><br><span class=line><span class=comment>// 钩子方法</span></span><br><span class=line> This <span class=keyword>class</span> <span class="title class_">provides</span> <span class=keyword>protected</span> overridable <span class="title function_">beforeExecute</span><span class=params>(Thread, Runnable)</span> and <span class="title function_">afterExecute</span><span class=params>(Runnable, Throwable)</span> methods that are called before and after execution of each task. These can be used to manipulate the execution environment; <span class=keyword>for</span> example, reinitializing ThreadLocals, gathering statistics, or adding log entries. Additionally, method terminated can be overridden to perform any special processing that needs to be done once the Executor has fully terminated.</span><br><span class=line> <span class=comment>// 该类提供 protected 的可重载 beforeExecute(Thread, Runnable) 和 afterExecute(Runnable, Throwable) 方法,可在每个任务执行前后调用。这些方法可用于操纵执行环境,例如,重新初始化线程位置、收集统计数据或添加日志条目。此外,还可以重写终止方法,以便在执行器完全终止后执行任何需要进行的特殊处理。(一些动态线程池技术就用到了这两个方法)</span></span><br><span class=line> If hook or callback methods <span class=keyword>throw</span> exceptions, internal worker threads may in turn fail and abruptly terminate.</span><br><span class=line> <span class=comment>// 如果钩子或回调方法抛出异常,内部工作线程可能会失败并突然终止。</span></span><br><span class=line>Queue maintenance</span><br><span class=line><span class=comment>// 队列维护</span></span><br><span class=line> Method <span class="title function_">getQueue</span><span class=params>()</span> allows access to the work queue <span class=keyword>for</span> purposes of monitoring and debugging. Use of <span class=built_in>this</span> method <span class=keyword>for</span> any other purpose is strongly discouraged. Two supplied methods, remove(Runnable) and purge are available to assist in storage reclamation when large numbers of queued tasks become cancelled.</span><br><span class=line> <span class=comment>// 方法 getQueue() 允许访问工作队列,以便进行监控和调试。强烈建议不要将此方法用于任何其他目的。当大量队列任务被取消时,可使用 remove(Runnable) 和 purge 这两个提供的方法来帮助回收存储空间。(不建议直接将获取到的队列进行修改操作)</span></span><br><span class=line>Finalization</span><br><span class=line><span class=comment>// 终止</span></span><br><span class=line> A pool that is no longer referenced in a program AND has no remaining threads will be shutdown automatically. If you would like to ensure that unreferenced pools are reclaimed even <span class=keyword>if</span> users forget to call shutdown, then you must arrange that unused threads eventually die, by setting appropriate keep-alive times, using a lower bound of zero core threads and/or setting <span class="title function_">allowCoreThreadTimeOut</span><span class=params>(<span class=type>boolean</span>)</span>.</span><br><span class=line> <span class=comment>// 程序中不再引用且没有剩余线程的池将自动关闭。如果要确保即使用户忘记调用 shutdown 也能回收未引用的池,则必须通过设置适当的保持连接时间、使用零核心线程下限和/或设置 allowCoreThreadTimeOut(boolean) 来使得未使用的线程最终被停止。</span></span><br></pre></table></figure><p>通过前面的简单翻译我们就能大致略窥得线程池配置全貌,继续看一个构造方法<figure class="highlight java"><table><tr><td class=gutter><pre><span class=line>1</span><br><span class=line>2</span><br><span class=line>3</span><br><span class=line>4</span><br><span class=line>5</span><br><span class=line>6</span><br><span class=line>7</span><br><span class=line>8</span><br><span class=line>9</span><br><span class=line>10</span><br></pre><td class=code><pre><span class=line><span class=keyword>public</span> <span class="title function_">ThreadPoolExecutor</span><span class=params>(<span class=type>int</span> corePoolSize,</span></span><br><span class=line><span class=params> <span class=type>int</span> maximumPoolSize,</span></span><br><span class=line><span class=params> <span class=type>long</span> keepAliveTime,</span></span><br><span class=line><span class=params> TimeUnit unit,</span></span><br><span class=line><span class=params> BlockingQueue&LTRunnable> workQueue)</span> {</span><br><span class=line> <span class=built_in>this</span>(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,</span><br><span class=line> Executors.defaultThreadFactory(), defaultHandler);</span><br><span class=line>}</span><br><span class=line><span class=keyword>private</span> <span class=keyword>static</span> <span class=keyword>final</span> <span class=type>RejectedExecutionHandler</span> <span class=variable>defaultHandler</span> <span class=operator>=</span></span><br><span class=line> <span class=keyword>new</span> <span class="title class_">AbortPolicy</span>();</span><br></pre></table></figure><p>这个构造方法就主要配置了 <code>corePoolSize</code> 核心线程数,<code>maximumPoolSize</code> 最大线程数, <code>keepAliveTime</code> 线程保活时间,<code>unit</code> 时间单位,<code>workQueue</code> 工作队列,而传入后可以看到使用了默认的线程工厂和默认的拒绝处理器<figure class="highlight java"><table><tr><td class=gutter><pre><span class=line>1</span><br><span class=line>2</span><br><span class=line>3</span><br><span class=line>4</span><br><span class=line>5</span><br><span class=line>6</span><br><span class=line>7</span><br><span class=line>8</span><br><span class=line>9</span><br><span class=line>10</span><br><span class=line>11</span><br><span class=line>12</span><br><span class=line>13</span><br><span class=line>14</span><br><span class=line>15</span><br><span class=line>16</span><br><span class=line>17</span><br><span class=line>18</span><br><span class=line>19</span><br><span class=line>20</span><br><span class=line>21</span><br><span class=line>22</span><br><span class=line>23</span><br><span class=line>24</span><br></pre><td class=code><pre><span class=line><span class=keyword>public</span> <span class="title function_">ThreadPoolExecutor</span><span class=params>(<span class=type>int</span> corePoolSize,</span></span><br><span class=line><span class=params> <span class=type>int</span> maximumPoolSize,</span></span><br><span class=line><span class=params> <span class=type>long</span> keepAliveTime,</span></span><br><span class=line><span class=params> TimeUnit unit,</span></span><br><span class=line><span class=params> BlockingQueue&LTRunnable> workQueue,</span></span><br><span class=line><span class=params> ThreadFactory threadFactory,</span></span><br><span class=line><span class=params> RejectedExecutionHandler handler)</span> {</span><br><span class=line> <span class=keyword>if</span> (corePoolSize < <span class=number>0</span> ||</span><br><span class=line> maximumPoolSize <= <span class=number>0</span> ||</span><br><span class=line> maximumPoolSize < corePoolSize ||</span><br><span class=line> keepAliveTime < <span class=number>0</span>)</span><br><span class=line> <span class=keyword>throw</span> <span class=keyword>new</span> <span class="title class_">IllegalArgumentException</span>();</span><br><span class=line> <span class=keyword>if</span> (workQueue == <span class=literal>null</span> || threadFactory == <span class=literal>null</span> || handler == <span class=literal>null</span>)</span><br><span class=line> <span class=keyword>throw</span> <span class=keyword>new</span> <span class="title class_">NullPointerException</span>();</span><br><span class=line> <span class=built_in>this</span>.acc = System.getSecurityManager() == <span class=literal>null</span> ?</span><br><span class=line> <span class=literal>null</span> :</span><br><span class=line> AccessController.getContext();</span><br><span class=line> <span class=built_in>this</span>.corePoolSize = corePoolSize;</span><br><span class=line> <span class=built_in>this</span>.maximumPoolSize = maximumPoolSize;</span><br><span class=line> <span class=built_in>this</span>.workQueue = workQueue;</span><br><span class=line> <span class=built_in>this</span>.keepAliveTime = unit.toNanos(keepAliveTime);</span><br><span class=line> <span class=built_in>this</span>.threadFactory = threadFactory;</span><br><span class=line> <span class=built_in>this</span>.handler = handler;</span><br><span class=line>}</span><br></pre></table></figure><p>最终会执行到这里做一些校验判断,包括几个参数校验和配置赋值</div><footer class=post-footer><div class="affiliate-creative affiliate-creative--post-end" data-affiliate-id=tencent-cloud-general><a rel="sponsored noopener" aria-label=腾讯云产品优惠 href=https://cloud.tencent.com/act/cps/redirect?redirect=2446&cps_key=2e33a1eedb380997d03618b4a5ba6ca7&from=console target=_blank><img alt=腾讯云服务器、数据库和云产品优惠 decoding=async height=419 loading=lazy src=/uploads/affiliate/tencent-cloud-general.webp width=690> </a><span class=affiliate-disclosure>推广</span></div><div class=reward-container><div>请我一杯咖啡吧!</div><button>赞赏</button><div class=post-reward><div><img alt="Nicksxs 微信" src=https://i.loli.net/2020/01/12/NUlWanT31E8LQGx.png><span>微信</span></div><div><img alt="Nicksxs 支付宝" src=https://ooo.0o0.ooo/2016/08/17/57b421e773057.jpg><span>支付宝</span></div></div></div><div class=post-copyright><ul><li class=post-copyright-author><strong>本文作者: </strong>Nicksxs<li class=post-copyright-link><strong>本文链接:</strong> <a title="Java 线程池系列-第一篇" href=https://nicksxs.me/2024/02/11/Java-%E7%BA%BF%E7%A8%8B%E6%B1%A0%E7%B3%BB%E5%88%97-%E7%AC%AC%E4%B8%80%E7%AF%87/>https://nicksxs.me/2024/02/11/Java-线程池系列-第一篇/</a><li class=post-copyright-license><strong>版权声明: </strong>本博客所有文章除特别声明外,均采用 <a href=https://creativecommons.org/licenses/by-nc-sa/4.0/ rel=noopener target=_blank><i class="fab fa-fw fa-creative-commons"></i>BY-NC-SA</a> 许可协议。转载请注明出处!</ul></div><div class=post-tags><a href=/tags/Java/ rel=tag># Java</a></div><div class=post-nav><div class=post-nav-item><a title="Java 线程池系列-准备篇" href=/2024/02/04/Java-%E7%BA%BF%E7%A8%8B%E6%B1%A0%E7%B3%BB%E5%88%97-%E5%87%86%E5%A4%87%E7%AF%87/ rel=prev><i class="fa fa-angle-left"></i> Java 线程池系列-准备篇</a></div><div class=post-nav-item><a title="Java 线程池系列-第二篇" href=/2024/02/18/Java-%E7%BA%BF%E7%A8%8B%E6%B1%A0%E7%B3%BB%E5%88%97-%E7%AC%AC%E4%BA%8C%E7%AF%87/ rel=next>Java 线程池系列-第二篇 <i class="fa fa-angle-right"></i></a></div></div></footer></article></div><div class=comments id=disqus_thread><noscript>Please enable JavaScript to view the comments powered by Disqus.</noscript></div></div></main><footer class=footer><div class=footer-inner><div class=beian><a href=https://beian.miit.gov.cn/ rel=noopener target=_blank>浙ICP备16002580号-2 </a><img alt src=/uploads/beian.png><a href=https://beian.mps.gov.cn/#/query/webSearch?code=33010602011094 rel=noopener target=_blank>浙公网安备 33010602011094号</a></div><div class=copyright>© <span itemprop=copyrightYear>2026</span><span class=with-love><i class="fa fa-heart"></i> </span><span class=author itemprop=copyrightHolder>Nicksxs</span></div></div></footer><div class="toggle sidebar-toggle" role=button><span class=toggle-line></span><span class=toggle-line></span><span class=toggle-line></span></div><div class=sidebar-dimmer></div><div aria-label=返回顶部 class=back-to-top role=button><i class="fa fa-arrow-up fa-lg"></i><span>0%</span></div><a aria-label="在 GitHub 上关注我" title="在 GitHub 上关注我" class=github-corner href=https://github.com/nicksxs rel=noopener target=_blank><svg viewbox="0 0 250 250" aria-hidden=true height=80 width=80><path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path><path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" style="transform-origin:130px 106px" class=octo-arm fill=currentColor></path><path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" class=octo-body fill=currentColor></path></svg></a><noscript><div class=noscript-warning>Theme NexT works best with JavaScript enabled</div></noscript><script data-cloudflare-page-counter-config type=application/json>{"enable":true,"endpoint":"https://counter.nicksxs.me","site":"nicksxs","local_cache":true,"timeout":5000,"icon":"far fa-eye","item_text":true}</script><script src=/js/cloudflare-page-counter.js></script><script class=next-config data-name=disqus type=application/json>{"enable":true,"shortname":"nicksxs","count":false,"i18n":{"disqus":"disqus"}}</script><script defer src=/js/third-party/comments/disqus.js></script>