尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
第四章 JUC 常见并发工具类(java.util.concurrent,面试核心)
定位JUC是Java标准库提供的并发编程工具包包含任务封装、可重入锁、原子类、线程池、同步工具等比原生synchronized更灵活、功能更强。1. Callable 接口 FutureTask解决的问题Runnable的void run()没有返回值也不能抛出受检异常如果需要线程执行完带回结果原生写法需要自己写同步、等待、结果类代码繁琐易错。Callable 接口适合于想让某个线程执行一个逻辑并且返回结果的时候相比之下Runnable不关注结果public interface CallableV { V call() throws Exception; }带泛型V表示返回值的类型call()方法可以返回结果也可以抛出异常FutureTaskCallable不能直接传给Thread执行需要用FutureTask包装。作用保存Callable的执行结果主线程可以通过它阻塞等待任务完成并获取结果。通俗比喻点麻辣烫后厨开始做前台给你一张小票FutureTask随时可以凭小票看做好了没。完整代码示例// 定义带返回值的任务计算1~1000的和 CallableInteger callable new CallableInteger() { Override public Integer call() throws Exception { int sum 0; for (int i 1; i 1000; i) { sum i; } return sum; } }; FutureTaskInteger futureTask new FutureTask(callable); new Thread(futureTask).start(); // 主线程阻塞等待直到任务完成拿到结果 //此处的get就能获取到callable里面的 返回结果 //由于线程是并发执行的执行到主线程的get的时候t线程可能还没有执行完 //没有执行完的话就会阻塞 Integer result futureTask.get(); System.out.println(result);面试核心点Runnable无返回值不抛出受检异常Callable有返回值可抛出异常必须搭配FutureTask使用futureTask.get()阻塞等待任务执行完成获取返回值2. ReentrantLock 可重入互斥锁和synchronized定位相同都是实现线程互斥保证线程安全但ReentrantLock是Java类实现功能更灵活。基础用法ReentrantLock lock new ReentrantLock(); lock.lock(); // 加锁拿不到锁就死等 try { // 临界区业务代码 } finally { lock.unlock(); // 必须手动解锁写在finally防止异常遗漏 }增强功能tryLock(long timeout)尝试加锁等待指定时间还拿不到锁就放弃不会死等。公平锁支持构造方法传入true即可开启公平锁遵守先来后到。ReentrantLock fairLock new ReentrantLock(true); // 公平锁精准唤醒搭配Condition类可以指定唤醒某个/某组等待线程而synchronized的notify()只能随机唤醒一个。synchronized vs ReentrantLock 对比面试必背维度synchronizedReentrantLock实现层面JVM关键字底层C实现JDK标准库类Java代码实现锁释放退出同步块自动释放必须手动调用unlock加锁行为拿不到锁就死等lock()死等tryLock可超时放弃公平性只能非公平锁默认非公平可手动开启公平锁等待唤醒wait/notify随机唤醒Condition可精准唤醒指定线程锁类型可重入锁可重入锁选型建议锁竞争不激烈、代码简单优先用synchronized自动释放不易出错锁竞争激烈、需要超时放弃、公平锁、精准唤醒用ReentrantLock3. 原子类java.util.concurrent.atomic原理内部基于CAS volatile实现不需要加锁就能完成线程安全的数值操作性能远高于synchronized。常见原子类AtomicBoolean原子布尔值AtomicInteger原子整数AtomicLong原子长整型AtomicReference原子引用对象AtomicStampedReference带版本号的原子引用解决ABA问题AtomicInteger 常用方法方法作用对应普通操作getAndIncrement()返回旧值再自增iincrementAndGet()先自增返回新值igetAndDecrement()返回旧值再自减i--decrementAndGet()先自减返回新值--iaddAndGet(int delta)加上delta返回新值i delta面试考点AtomicInteger底层是CAS自旋实现的乐观锁不需要重量级锁高并发下性能优于synchronized。4. 线程池核心思想线程创建销毁比进程轻量但频繁创建销毁依然有开销。线程池提前创建一批线程复用任务来了直接分配线程执行任务完成线程不销毁放回池中等待下一个任务。Executors 工厂类快捷创建线程池Executors是线程池工厂类提供4种常用线程池底层都是封装ThreadPoolExecutor。工厂方法特点newFixedThreadPool(n)固定线程数量的线程池newCachedThreadPool()线程数动态伸缩空闲线程缓存复用newSingleThreadExecutor()只有一个线程任务串行执行newScheduledThreadPool(n)支持延迟、定时执行任务多线程版定时器注意生产环境不推荐直接用Executors因为部分线程池队列无界、最大线程数无界高并发下容易OOM。ThreadPoolExecutor 七大核心参数面试必考可以理解为开一家公司corePoolSize核心线程数正式员工常驻不辞退maximumPoolSize最大线程数正式员工 临时工的总上限keepAliveTime空闲存活时间临时工空闲多久就被辞退TimeUnit unit时间单位BlockingQueueRunnable workQueue阻塞任务队列存放等待执行的任务ThreadFactory threadFactory线程工厂统一创建线程可自定义线程名称RejectedExecutionHandler handler拒绝策略任务超过承载时的处理方式四种拒绝策略AbortPolicy【默认】直接抛出RejectedExecutionException异常CallerRunsPolicy由提交任务的线程自己执行这个任务DiscardOldestPolicy丢弃队列中排队最久的任务再尝试提交新任务DiscardPolicy直接丢弃新来的任务不抛异常线程池执行流程必背提交任务 → 核心线程未满 → 创建核心线程执行任务核心线程已满 → 任务进入阻塞队列排队队列也满了 → 创建非核心临时线程执行任务总线程数达到最大线程数 → 触发拒绝策略任务高峰过后非核心线程空闲超过keepAliveTime→ 销毁回收核心线程保留5. Semaphore 信号量锁本质也是一种特殊的信号量加锁操作p操作1-0 解锁操作V操作0-1 二元信号量核心作用表示可用资源的个数本质是一个原子计数器控制同时访问资源的最大线程数。PV操作acquire()P操作申请一个资源计数器-1计数器为0则阻塞等待release()V操作释放一个资源计数器1唤醒等待的线程通俗比喻PDF原文停车场剩余车位牌。车开进去车位-1开出来车位1车位为0时门口的车等待。代码示例// 初始4个许可最多4个线程同时执行 Semaphore semaphore new Semaphore(4); Runnable task () - { try { semaphore.acquire(); // 申请资源 System.out.println(获取到资源执行任务); Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } finally { semaphore.release(); // 释放资源 } }; // 启动20个线程最多同时4个运行 for (int i 0; i 20; i) { new Thread(task).start(); }适用场景限流、控制并发数、共享资源池管理。开发中需要申请资源的场景6. CountDownLatch 倒计时锁存器核心作用等待N个任务全部执行完成主线程再继续往下走。核心方法CountDownLatch(int count)构造方法指定需要等待的任务数量countDown()每个任务执行完调用一次计数器-1await()主线程调用阻塞等待直到计数器减到0通俗比喻跑步比赛10个选手就位枪响同时出发必须等所有选手都冲过终点才能公布成绩。代码示例// 等待10个任务全部完成 CountDownLatch latch new CountDownLatch(10); Runnable task () - { try { Thread.sleep((long) (Math.random() * 1000)); } catch (InterruptedException e) {} latch.countDown(); // 任务完成计数减一 }; for (int i 0; i 10; i) { new Thread(task).start(); } latch.await(); // 主线程阻塞直到所有任务完成 System.out.println(全部任务执行完毕);适用场景多任务并行执行最后统一汇总结果主流程等待多个子任务全部完成。第四章 面试高频总结Callable带返回值FutureTask用来接收结果get()阻塞等待。ReentrantLock是可重入锁支持超时、公平锁、精准唤醒需要手动解锁。原子类基于CAS实现无锁线程安全适合高并发数值操作。线程池7大参数、4种拒绝策略、执行流程是面试必考题。Semaphore控制最大并发数CountDownLatch等待多任务全部完成。第四章的内容就全部梳理完了覆盖了PDF里所有工具类的定义、用法、比喻、场景和面试考点。确认理解后我们进入第五章线程安全集合类的详细讲解。
RELATED

相关推荐

google-drive-ocamlfuse 的 DriveRootResolution 模块:根目录解析与合成知名资源的设计实现全解

google-drive-ocamlfuse 的 DriveRootResolution 模块:根目录解析与合成知名资源的设计实现全解

存储 【免费下载链接】google-drive-ocamlfuse FUSE filesystem over Google Drive 项目地址: https://gitcode.com/gh_mirrors/go/google-drive-ocamlfuse 点击查看 免费下载 本文围绕仓库中已归档的重构计划 drive-root-resolution-extraction/plan.md 展开&…

📅 2026/10/10 16:28:12
AI大模型如何抓取和推荐淮南本地商户?GEO技术链路与POI权重算法拆解

AI大模型如何抓取和推荐淮南本地商户?GEO技术链路与POI权重算法拆解

一、技术背景:AI大模型正在重构本地服务流量分发 传统本地服务流量分发依赖搜索引擎关键词竞价、平台排名购买、信息流广告投放等付费模式。2026年1月起,豆包、DeepSeek、文心一言、通义千问等生成式AI大模型逐渐成为新一代本地服务查询入口。用户不再打…

📅 2026/10/10 16:28:12
Pulse Relay Runtime 契约解析:桌面与移动端中继的端到端加密、持久化边界与移动能力治理

Pulse Relay Runtime 契约解析:桌面与移动端中继的端到端加密、持久化边界与移动能力治理

可观测性运维后端 【免费下载链接】Pulse Real-time monitoring dashboard for Proxmox VE, PBS, Docker, Kubernetes, TrueNAS and vSphere. Self-hosted, with smart alerts and AI patrols that catch silent failures. 项目地址: https://gitcode.com/gh_mirror…

📅 2026/10/10 16:28:12
MORE NEWS

更多资讯

📰

RLMD信号分解算法详解:原理、MATLAB实现与故障特征提取

这段时间一直在折腾信号分解,尤其是有一次处理一组旋转机械的振动仿真数据时,FFT频谱上看不出任何故障特征,试了经验模态分解又觉得模态混叠得一塌糊涂。后来我把目光转向鲁棒局部均值分解(RLMD),整个分析流…

📰

LangGraph生产级落地:状态契约、节点原子性与Checkpointer实战

1. 这不是又一个“LangGraph入门课”,而是一份被反复验证的工程化落地手记你点开这个标题,大概率刚被某条“LangGraph三分钟上手”视频劝退过——代码跑通了,但加个重试逻辑就报错;文档里写的StateGraph明明支持分支,实…

📰

乐观锁与幂等性实战:从版本号到幂等表的状态更新方案

1. 先理清楚:乐观锁与幂等性到底在解决什么问题在做状态更新类接口时,我见过太多线上事故了。库存扣成负数、订单被重复创建、一张工单被两个运营同时改出了两种结果,这些问题的根子都指向两个词——乐观锁和幂等性。很多人把这两个概念混着说…

📰

MySQL逻辑备份工具mysqldump:参数详解与恢复实战

做MySQL运维和开发的朋友,迟早会跟mysqldump打交道。它就是MySQL自带的逻辑备份工具,能把数据库里的表结构、数据、视图、存储过程这些内容,按照SQL语句的形式导出成一个文本文件。这个文件你用编辑器就能打开查看,后续不管是数据…

📰

LangGraph生产实践:状态机设计、条件边避坑与Redis持久化

1. 这不是又一个“LangGraph速成班”,而是一份能直接上手写生产代码的工程实践手册你点开这个标题,大概率正卡在某个节点上:可能是刚学完LangChain基础,对着官方文档里那个StateGraph示例反复看了三遍,还是搞不清add_n…

📰

一文搞懂栈保护指令:从原理到工程实践

我们经常在安全公告和漏洞分析里看到"栈保护"这个词,但真让自己去编译一个项目、决定要不要开、开哪个级别时,很多人其实心里没底。尤其是现在主流的 C/C 编译器都内置了以指令选项形式存在的栈保护机制,比如大家常听到的栈金丝雀&…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬