learn.lianglianglee.com/专栏/Java 并发编程 78 讲-完/11 线程池有哪 4 种拒绝策略?.md.html
2022-05-11 18:57:05 +08:00

1345 lines
31 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<!-- saved from url=(0046)https://kaiiiz.github.io/hexo-theme-book-demo/ -->
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=no">
<link rel="icon" href="/static/favicon.png">
<title>11 线程池有哪 4 种拒绝策略?.md.html</title>
<!-- Spectre.css framework -->
<link rel="stylesheet" href="/static/index.css">
<!-- theme css & js -->
<meta name="generator" content="Hexo 4.2.0">
</head>
<body>
<div class="book-container">
<div class="book-sidebar">
<div class="book-brand">
<a href="/">
<img src="/static/favicon.png">
<span>技术文章摘抄</span>
</a>
</div>
<div class="book-menu uncollapsible">
<ul class="uncollapsible">
<li><a href="/" class="current-tab">首页</a></li>
</ul>
<ul class="uncollapsible">
<li><a href="../">上一级</a></li>
</ul>
<ul class="uncollapsible">
<li>
<a href="/专栏/Java 并发编程 78 讲-完/00 由点及面,搭建你的 Java 并发知识网.md.html">00 由点及面,搭建你的 Java 并发知识网.md.html</a>
</li>
<li>
<a href="/专栏/Java 并发编程 78 讲-完/01 为何说只有 1 种实现线程的方法?.md.html">01 为何说只有 1 种实现线程的方法?.md.html</a>
</li>
<li>
<a href="/专栏/Java 并发编程 78 讲-完/02 如何正确停止线程?为什么 volatile 标记位的停止方法是错误的?.md.html">02 如何正确停止线程?为什么 volatile 标记位的停止方法是错误的?.md.html</a>
</li>
<li>
<a href="/专栏/Java 并发编程 78 讲-完/03 线程是如何在 6 种状态之间转换的?.md.html">03 线程是如何在 6 种状态之间转换的?.md.html</a>
</li>
<li>
<a href="/专栏/Java 并发编程 78 讲-完/04 waitnotifynotifyAll 方法的使用注意事项?.md.html">04 waitnotifynotifyAll 方法的使用注意事项?.md.html</a>
</li>
<li>
<a href="/专栏/Java 并发编程 78 讲-完/05 有哪几种实现生产者消费者模式的方法?.md.html">05 有哪几种实现生产者消费者模式的方法?.md.html</a>
</li>
<li>
<a href="/专栏/Java 并发编程 78 讲-完/06 一共有哪 3 类线程安全问题?.md.html">06 一共有哪 3 类线程安全问题?.md.html</a>
</li>
<li>
<a href="/专栏/Java 并发编程 78 讲-完/07 哪些场景需要额外注意线程安全问题?.md.html">07 哪些场景需要额外注意线程安全问题?.md.html</a>
</li>
<li>
<a href="/专栏/Java 并发编程 78 讲-完/08 为什么多线程会带来性能问题?.md.html">08 为什么多线程会带来性能问题?.md.html</a>
</li>
<li>
<a href="/专栏/Java 并发编程 78 讲-完/09 使用线程池比手动创建线程好在哪里?.md.html">09 使用线程池比手动创建线程好在哪里?.md.html</a>
</li>
<li>
<a href="/专栏/Java 并发编程 78 讲-完/10 线程池的各个参数的含义?.md.html">10 线程池的各个参数的含义?.md.html</a>
</li>
<li>
<a class="current-tab" href="/专栏/Java 并发编程 78 讲-完/11 线程池有哪 4 种拒绝策略?.md.html">11 线程池有哪 4 种拒绝策略?.md.html</a>
</li>
<li>
<a href="/专栏/Java 并发编程 78 讲-完/12 有哪 6 种常见的线程池?什么是 Java8 的 ForkJoinPool.md.html">12 有哪 6 种常见的线程池?什么是 Java8 的 ForkJoinPool.md.html</a>
</li>
<li>
<a href="/专栏/Java 并发编程 78 讲-完/13 线程池常用的阻塞队列有哪些?.md.html">13 线程池常用的阻塞队列有哪些?.md.html</a>
</li>
<li>
<a href="/专栏/Java 并发编程 78 讲-完/14 为什么不应该自动创建线程池?.md.html">14 为什么不应该自动创建线程池?.md.html</a>
</li>
<li>
<a href="/专栏/Java 并发编程 78 讲-完/15 合适的线程数量是多少CPU 核心数和线程数的关系?.md.html">15 合适的线程数量是多少CPU 核心数和线程数的关系?.md.html</a>
</li>
<li>
<a href="/专栏/Java 并发编程 78 讲-完/16 如何根据实际需要,定制自己的线程池?.md.html">16 如何根据实际需要,定制自己的线程池?.md.html</a>
</li>
<li>
<a href="/专栏/Java 并发编程 78 讲-完/17 如何正确关闭线程池shutdown 和 shutdownNow 的区别?.md.html">17 如何正确关闭线程池shutdown 和 shutdownNow 的区别?.md.html</a>
</li>
<li>
<a href="/专栏/Java 并发编程 78 讲-完/18 线程池实现“线程复用”的原理?.md.html">18 线程池实现“线程复用”的原理?.md.html</a>
</li>
<li>
<a href="/专栏/Java 并发编程 78 讲-完/19 你知道哪几种锁?分别有什么特点?.md.html">19 你知道哪几种锁?分别有什么特点?.md.html</a>
</li>
<li>
<a href="/专栏/Java 并发编程 78 讲-完/20 悲观锁和乐观锁的本质是什么?.md.html">20 悲观锁和乐观锁的本质是什么?.md.html</a>
</li>
<li>
<a href="/专栏/Java 并发编程 78 讲-完/21 如何看到 synchronized 背后的“monitor 锁”?.md.html">21 如何看到 synchronized 背后的“monitor 锁”?.md.html</a>
</li>
<li>
<a href="/专栏/Java 并发编程 78 讲-完/22 synchronized 和 Lock 孰优孰劣,如何选择?.md.html">22 synchronized 和 Lock 孰优孰劣,如何选择?.md.html</a>
</li>
<li>
<a href="/专栏/Java 并发编程 78 讲-完/23 Lock 有哪几个常用方法?分别有什么用?.md.html">23 Lock 有哪几个常用方法?分别有什么用?.md.html</a>
</li>
<li>
<a href="/专栏/Java 并发编程 78 讲-完/24 讲一讲公平锁和非公平锁,为什么要“非公平”?.md.html">24 讲一讲公平锁和非公平锁,为什么要“非公平”?.md.html</a>
</li>
<li>
<a href="/专栏/Java 并发编程 78 讲-完/25 读写锁 ReadWriteLock 获取锁有哪些规则?.md.html">25 读写锁 ReadWriteLock 获取锁有哪些规则?.md.html</a>
</li>
<li>
<a href="/专栏/Java 并发编程 78 讲-完/26 读锁应该插队吗?什么是读写锁的升降级?.md.html">26 读锁应该插队吗?什么是读写锁的升降级?.md.html</a>
</li>
<li>
<a href="/专栏/Java 并发编程 78 讲-完/27 什么是自旋锁?自旋的好处和后果是什么呢?.md.html">27 什么是自旋锁?自旋的好处和后果是什么呢?.md.html</a>
</li>
<li>
<a href="/专栏/Java 并发编程 78 讲-完/28 JVM 对锁进行了哪些优化?.md.html">28 JVM 对锁进行了哪些优化?.md.html</a>
</li>
<li>
<a href="/专栏/Java 并发编程 78 讲-完/29 HashMap 为什么是线程不安全的?.md.html">29 HashMap 为什么是线程不安全的?.md.html</a>
</li>
<li>
<a href="/专栏/Java 并发编程 78 讲-完/30 ConcurrentHashMap 在 Java7 和 8 有何不同?.md.html">30 ConcurrentHashMap 在 Java7 和 8 有何不同?.md.html</a>
</li>
<li>
<a href="/专栏/Java 并发编程 78 讲-完/31 为什么 Map 桶中超过 8 个才转为红黑树?.md.html">31 为什么 Map 桶中超过 8 个才转为红黑树?.md.html</a>
</li>
<li>
<a href="/专栏/Java 并发编程 78 讲-完/32 同样是线程安全ConcurrentHashMap 和 Hashtable 的区别.md.html">32 同样是线程安全ConcurrentHashMap 和 Hashtable 的区别.md.html</a>
</li>
<li>
<a href="/专栏/Java 并发编程 78 讲-完/33 CopyOnWriteArrayList 有什么特点?.md.html">33 CopyOnWriteArrayList 有什么特点?.md.html</a>
</li>
<li>
<a href="/专栏/Java 并发编程 78 讲-完/34 什么是阻塞队列?.md.html">34 什么是阻塞队列?.md.html</a>
</li>
<li>
<a href="/专栏/Java 并发编程 78 讲-完/35 阻塞队列包含哪些常用的方法add、offer、put 等方法的区别?.md.html">35 阻塞队列包含哪些常用的方法add、offer、put 等方法的区别?.md.html</a>
</li>
<li>
<a href="/专栏/Java 并发编程 78 讲-完/36 有哪几种常见的阻塞队列?.md.html">36 有哪几种常见的阻塞队列?.md.html</a>
</li>
<li>
<a href="/专栏/Java 并发编程 78 讲-完/37 阻塞和非阻塞队列的并发安全原理是什么?.md.html">37 阻塞和非阻塞队列的并发安全原理是什么?.md.html</a>
</li>
<li>
<a href="/专栏/Java 并发编程 78 讲-完/38 如何选择适合自己的阻塞队列?.md.html">38 如何选择适合自己的阻塞队列?.md.html</a>
</li>
<li>
<a href="/专栏/Java 并发编程 78 讲-完/39 原子类是如何利用 CAS 保证线程安全的?.md.html">39 原子类是如何利用 CAS 保证线程安全的?.md.html</a>
</li>
<li>
<a href="/专栏/Java 并发编程 78 讲-完/40 AtomicInteger 在高并发下性能不好,如何解决?为什么?.md.html">40 AtomicInteger 在高并发下性能不好,如何解决?为什么?.md.html</a>
</li>
<li>
<a href="/专栏/Java 并发编程 78 讲-完/41 原子类和 volatile 有什么异同?.md.html">41 原子类和 volatile 有什么异同?.md.html</a>
</li>
<li>
<a href="/专栏/Java 并发编程 78 讲-完/42 AtomicInteger 和 synchronized 的异同点?.md.html">42 AtomicInteger 和 synchronized 的异同点?.md.html</a>
</li>
<li>
<a href="/专栏/Java 并发编程 78 讲-完/43 Java 8 中 Adder 和 Accumulator 有什么区别?.md.html">43 Java 8 中 Adder 和 Accumulator 有什么区别?.md.html</a>
</li>
<li>
<a href="/专栏/Java 并发编程 78 讲-完/44 ThreadLocal 适合用在哪些实际生产的场景中?.md.html">44 ThreadLocal 适合用在哪些实际生产的场景中?.md.html</a>
</li>
<li>
<a href="/专栏/Java 并发编程 78 讲-完/45 ThreadLocal 是用来解决共享资源的多线程访问的问题吗?.md.html">45 ThreadLocal 是用来解决共享资源的多线程访问的问题吗?.md.html</a>
</li>
<li>
<a href="/专栏/Java 并发编程 78 讲-完/46 多个 ThreadLocal 在 Thread 中的 threadlocals 里是怎么存储的?.md.html">46 多个 ThreadLocal 在 Thread 中的 threadlocals 里是怎么存储的?.md.html</a>
</li>
<li>
<a href="/专栏/Java 并发编程 78 讲-完/47 内存泄漏——为何每次用完 ThreadLocal 都要调用 remove().md.html">47 内存泄漏——为何每次用完 ThreadLocal 都要调用 remove().md.html</a>
</li>
<li>
<a href="/专栏/Java 并发编程 78 讲-完/48 Callable 和 Runnable 的不同?.md.html">48 Callable 和 Runnable 的不同?.md.html</a>
</li>
<li>
<a href="/专栏/Java 并发编程 78 讲-完/49 Future 的主要功能是什么?.md.html">49 Future 的主要功能是什么?.md.html</a>
</li>
<li>
<a href="/专栏/Java 并发编程 78 讲-完/50 使用 Future 有哪些注意点Future 产生新的线程了吗?.md.html">50 使用 Future 有哪些注意点Future 产生新的线程了吗?.md.html</a>
</li>
<li>
<a href="/专栏/Java 并发编程 78 讲-完/51 如何利用 CompletableFuture 实现“旅游平台”问题?.md.html">51 如何利用 CompletableFuture 实现“旅游平台”问题?.md.html</a>
</li>
<li>
<a href="/专栏/Java 并发编程 78 讲-完/52 信号量能被 FixedThreadPool 替代吗?.md.html">52 信号量能被 FixedThreadPool 替代吗?.md.html</a>
</li>
<li>
<a href="/专栏/Java 并发编程 78 讲-完/53 CountDownLatch 是如何安排线程执行顺序的?.md.html">53 CountDownLatch 是如何安排线程执行顺序的?.md.html</a>
</li>
<li>
<a href="/专栏/Java 并发编程 78 讲-完/54 CyclicBarrier 和 CountdownLatch 有什么异同?.md.html">54 CyclicBarrier 和 CountdownLatch 有什么异同?.md.html</a>
</li>
<li>
<a href="/专栏/Java 并发编程 78 讲-完/55 Condition、object.wait() 和 notify() 的关系?.md.html">55 Condition、object.wait() 和 notify() 的关系?.md.html</a>
</li>
<li>
<a href="/专栏/Java 并发编程 78 讲-完/56 讲一讲什么是 Java 内存模型?.md.html">56 讲一讲什么是 Java 内存模型?.md.html</a>
</li>
<li>
<a href="/专栏/Java 并发编程 78 讲-完/57 什么是指令重排序?为什么要重排序?.md.html">57 什么是指令重排序?为什么要重排序?.md.html</a>
</li>
<li>
<a href="/专栏/Java 并发编程 78 讲-完/58 Java 中的原子操作有哪些注意事项?.md.html">58 Java 中的原子操作有哪些注意事项?.md.html</a>
</li>
<li>
<a href="/专栏/Java 并发编程 78 讲-完/59 什么是“内存可见性”问题?.md.html">59 什么是“内存可见性”问题?.md.html</a>
</li>
<li>
<a href="/专栏/Java 并发编程 78 讲-完/60 主内存和工作内存的关系?.md.html">60 主内存和工作内存的关系?.md.html</a>
</li>
<li>
<a href="/专栏/Java 并发编程 78 讲-完/61 什么是 happens-before 规则?.md.html">61 什么是 happens-before 规则?.md.html</a>
</li>
<li>
<a href="/专栏/Java 并发编程 78 讲-完/62 volatile 的作用是什么?与 synchronized 有什么异同?.md.html">62 volatile 的作用是什么?与 synchronized 有什么异同?.md.html</a>
</li>
<li>
<a href="/专栏/Java 并发编程 78 讲-完/63 单例模式的双重检查锁模式为什么必须加 volatile.md.html">63 单例模式的双重检查锁模式为什么必须加 volatile.md.html</a>
</li>
<li>
<a href="/专栏/Java 并发编程 78 讲-完/64 你知道什么是 CAS 吗?.md.html">64 你知道什么是 CAS 吗?.md.html</a>
</li>
<li>
<a href="/专栏/Java 并发编程 78 讲-完/65 CAS 和乐观锁的关系,什么时候会用到 CAS.md.html">65 CAS 和乐观锁的关系,什么时候会用到 CAS.md.html</a>
</li>
<li>
<a href="/专栏/Java 并发编程 78 讲-完/66 CAS 有什么缺点?.md.html">66 CAS 有什么缺点?.md.html</a>
</li>
<li>
<a href="/专栏/Java 并发编程 78 讲-完/67 如何写一个必然死锁的例子?.md.html">67 如何写一个必然死锁的例子?.md.html</a>
</li>
<li>
<a href="/专栏/Java 并发编程 78 讲-完/68 发生死锁必须满足哪 4 个条件?.md.html">68 发生死锁必须满足哪 4 个条件?.md.html</a>
</li>
<li>
<a href="/专栏/Java 并发编程 78 讲-完/69 如何用命令行和代码定位死锁?.md.html">69 如何用命令行和代码定位死锁?.md.html</a>
</li>
<li>
<a href="/专栏/Java 并发编程 78 讲-完/70 有哪些解决死锁问题的策略?.md.html">70 有哪些解决死锁问题的策略?.md.html</a>
</li>
<li>
<a href="/专栏/Java 并发编程 78 讲-完/71 讲一讲经典的哲学家就餐问题.md.html">71 讲一讲经典的哲学家就餐问题.md.html</a>
</li>
<li>
<a href="/专栏/Java 并发编程 78 讲-完/72 final 的三种用法是什么?.md.html">72 final 的三种用法是什么?.md.html</a>
</li>
<li>
<a href="/专栏/Java 并发编程 78 讲-完/73 为什么加了 final 却依然无法拥有“不变性”?.md.html">73 为什么加了 final 却依然无法拥有“不变性”?.md.html</a>
</li>
<li>
<a href="/专栏/Java 并发编程 78 讲-完/74 为什么 String 被设计为是不可变的?.md.html">74 为什么 String 被设计为是不可变的?.md.html</a>
</li>
<li>
<a href="/专栏/Java 并发编程 78 讲-完/75 为什么需要 AQSAQS 的作用和重要性是什么?.md.html">75 为什么需要 AQSAQS 的作用和重要性是什么?.md.html</a>
</li>
<li>
<a href="/专栏/Java 并发编程 78 讲-完/76 AQS 的内部原理是什么样的?.md.html">76 AQS 的内部原理是什么样的?.md.html</a>
</li>
<li>
<a href="/专栏/Java 并发编程 78 讲-完/77 AQS 在 CountDownLatch 等类中的应用原理是什么?.md.html">77 AQS 在 CountDownLatch 等类中的应用原理是什么?.md.html</a>
</li>
<li>
<a href="/专栏/Java 并发编程 78 讲-完/78 一份独家的 Java 并发工具图谱.md.html">78 一份独家的 Java 并发工具图谱.md.html</a>
</li>
</ul>
</div>
</div>
<div class="sidebar-toggle" onclick="sidebar_toggle()" onmouseover="add_inner()" onmouseleave="remove_inner()">
<div class="sidebar-toggle-inner"></div>
</div>
<script>
function add_inner() {
let inner = document.querySelector('.sidebar-toggle-inner')
inner.classList.add('show')
}
function remove_inner() {
let inner = document.querySelector('.sidebar-toggle-inner')
inner.classList.remove('show')
}
function sidebar_toggle() {
let sidebar_toggle = document.querySelector('.sidebar-toggle')
let sidebar = document.querySelector('.book-sidebar')
let content = document.querySelector('.off-canvas-content')
if (sidebar_toggle.classList.contains('extend')) { // show
sidebar_toggle.classList.remove('extend')
sidebar.classList.remove('hide')
content.classList.remove('extend')
} else { // hide
sidebar_toggle.classList.add('extend')
sidebar.classList.add('hide')
content.classList.add('extend')
}
}
function open_sidebar() {
let sidebar = document.querySelector('.book-sidebar')
let overlay = document.querySelector('.off-canvas-overlay')
sidebar.classList.add('show')
overlay.classList.add('show')
}
function hide_canvas() {
let sidebar = document.querySelector('.book-sidebar')
let overlay = document.querySelector('.off-canvas-overlay')
sidebar.classList.remove('show')
overlay.classList.remove('show')
}
</script>
<div class="off-canvas-content">
<div class="columns">
<div class="column col-12 col-lg-12">
<div class="book-navbar">
<!-- For Responsive Layout -->
<header class="navbar">
<section class="navbar-section">
<a onclick="open_sidebar()">
<i class="icon icon-menu"></i>
</a>
</section>
</header>
</div>
<div class="book-content" style="max-width: 960px; margin: 0 auto;
overflow-x: auto;
overflow-y: hidden;">
<div class="book-post">
<p id="tip" align="center"></p>
<div><h1>11 线程池有哪 4 种拒绝策略?</h1>
<p>本课时我们主要学习线程池有哪 4 种默认的拒绝策略。</p>
<h3>拒绝时机</h3>
<p>首先,新建线程池时可以指定它的任务拒绝策略,例如:</p>
<pre><code class="language-java">newThreadPoolExecutor(5, 10, 5, TimeUnit.SECONDS, new LinkedBlockingQueue&lt;&gt;(),
new ThreadPoolExecutor.DiscardOldestPolicy());
</code></pre>
<p>以便在必要的时候按照我们的策略来拒绝任务,那么拒绝任务的时机是什么呢?线程池会在以下两种情况下会拒绝新提交的任务。</p>
<ul>
<li>第一种情况是当我们调用 shutdown 等方法关闭线程池后,即便此时可能线程池内部依然有没执行完的任务正在执行,但是由于线程池已经关闭,此时如果再向线程池内提交任务,就会遭到拒绝。</li>
<li>第二种情况是线程池没有能力继续处理新提交的任务,也就是工作已经非常饱和的时候。</li>
</ul>
<p>我们具体讲一下第二种情况,也就是由于工作饱和导致的拒绝。比如新建一个线程池,使用容量上限为 10 的 ArrayBlockingQueue 作为任务队列,并且指定线程池的核心线程数为 5最大线程数为 10假设此时有 20 个耗时任务被提交在这种情况下线程池会首先创建核心数量的线程也就是5个线程来执行任务然后往队列里去放任务队列的 10 个容量被放满了之后,会继续创建新线程,直到达到最大线程数 10。此时线程池中一共有 20 个任务,其中 10 个任务正在被 10 个线程执行,还有 10 个任务在任务队列中等待,而且由于线程池的最大线程数量就是 10所以已经不能再增加更多的线程来帮忙处理任务了这就意味着此时线程池工作饱和这个时候再提交新任务时就会被拒绝。</p>
<p><img src="assets/CgoB5l3g0XCAWJKOAABzAQJB4SM657.png" alt="img" /></p>
<p>我们结合图示来分析上述情况,首先看右侧上方的队列部分,你可以看到目前队列已经满了,而图中队列下方的每个线程都在工作,且线程数已经达到最大值 10如果此时再有新的任务提交线程池由于没有能力继续处理新提交的任务所以就会拒绝。</p>
<p>我们了解了线程池拒绝任务的时机那么我们如何正确地选择拒绝策略呢Java 在 ThreadPoolExecutor 类中为我们提供了 4 种默认的拒绝策略来应对不同的场景,都实现了 RejectedExecutionHandler 接口,如图所示:</p>
<p><img src="assets/CgotOV3g0WWAVWVlAAEsBI6lEEA162.png" alt="img" /></p>
<p>接下来,我们将具体讲解这 4 种拒绝策略。</p>
<h3>拒绝策略</h3>
<ul>
<li>第一种拒绝策略是 AbortPolicy这种拒绝策略在拒绝任务时会直接抛出一个类型为 RejectedExecutionException 的 RuntimeException让你感知到任务被拒绝了于是你便可以根据业务逻辑选择重试或者放弃提交等策略。</li>
<li>第二种拒绝策略是 DiscardPolicy这种拒绝策略正如它的名字所描述的一样当新任务被提交后直接被丢弃掉也不会给你任何的通知相对而言存在一定的风险因为我们提交的时候根本不知道这个任务会被丢弃可能造成数据丢失。</li>
<li>第三种拒绝策略是 DiscardOldestPolicy如果线程池没被关闭且没有能力执行则会丢弃任务队列中的头结点通常是存活时间最长的任务这种策略与第二种不同之处在于它丢弃的不是最新提交的而是队列中存活时间最长的这样就可以腾出空间给新提交的任务但同理它也存在一定的数据丢失风险。</li>
<li>第四种拒绝策略是 CallerRunsPolicy相对而言它就比较完善了当有新任务提交后如果线程池没被关闭且没有能力执行则把这个任务交于提交任务的线程执行也就是谁提交任务谁就负责执行任务。这样做主要有两点好处。
<ul>
<li>第一点新提交的任务不会被丢弃,这样也就不会造成业务损失。</li>
<li>第二点好处是,由于谁提交任务谁就要负责执行任务,这样提交任务的线程就得负责执行任务,而执行任务又是比较耗时的,在这段期间,提交任务的线程被占用,也就不会再提交新的任务,减缓了任务提交的速度,相当于是一个负反馈。在此期间,线程池中的线程也可以充分利用这段时间来执行掉一部分任务,腾出一定的空间,相当于是给了线程池一定的缓冲期。</li>
</ul>
</li>
</ul>
</div>
</div>
<div>
<div style="float: left">
<a href="/专栏/Java 并发编程 78 讲-完/10 线程池的各个参数的含义?.md.html">上一页</a>
</div>
<div style="float: right">
<a href="/专栏/Java 并发编程 78 讲-完/12 有哪 6 种常见的线程池?什么是 Java8 的 ForkJoinPool.md.html">下一页</a>
</div>
</div>
</div>
</div>
</div>
</div>
<a class="off-canvas-overlay" onclick="hide_canvas()"></a>
</div>
<script defer src="https://static.cloudflareinsights.com/beacon.min.js/v652eace1692a40cfa3763df669d7439c1639079717194" integrity="sha512-Gi7xpJR8tSkrpF7aordPZQlW2DLtzUlZcumS8dMQjwDHEnw9I7ZLyiOj/6tZStRBGtGgN6ceN6cMH8z7etPGlw==" data-cf-beacon='{"rayId":"70997090eb9a3d60","version":"2021.12.0","r":1,"token":"1f5d475227ce4f0089a7cff1ab17c0f5","si":100}' crossorigin="anonymous"></script>
</body>
<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-NPSEEVD756"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag() {
dataLayer.push(arguments);
}
gtag('js', new Date());
gtag('config', 'G-NPSEEVD756');
var path = window.location.pathname
var cookie = getCookie("lastPath");
console.log(path)
if (path.replace("/", "") === "") {
if (cookie.replace("/", "") !== "") {
console.log(cookie)
document.getElementById("tip").innerHTML = "<a href='" + cookie + "'>跳转到上次进度</a>"
}
} else {
setCookie("lastPath", path)
}
function setCookie(cname, cvalue) {
var d = new Date();
d.setTime(d.getTime() + (180 * 24 * 60 * 60 * 1000));
var expires = "expires=" + d.toGMTString();
document.cookie = cname + "=" + cvalue + "; " + expires + ";path = /";
}
function getCookie(cname) {
var name = cname + "=";
var ca = document.cookie.split(';');
for (var i = 0; i < ca.length; i++) {
var c = ca[i].trim();
if (c.indexOf(name) === 0) return c.substring(name.length, c.length);
}
return "";
}
</script>
</html>