首页
/
行业洞察
/
正文
INDUSTRY INSIGHT · 深度
第四章 JUC 常见并发工具类(java.util.concurrent,面试核心)
📅 2026/10/10 16:27:59
✍️ 爱科研究院
👁 阅读 3,247
定位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里所有工具类的定义、用法、比喻、场景和面试考点。确认理解后我们进入第五章线程安全集合类的详细讲解。
📌 标签:
工业官网
设计趋势
AI 建站
SEO
获取完整报告 →
RELATED ARTICLES
推荐阅读
2026/10/10 16:27:59
google-drive-ocamlfuse 的 DriveRootResolution 模块:根目录解析与合成知名资源的设计实现全解
2026/10/10 16:27:59
AI大模型如何抓取和推荐淮南本地商户?GEO技术链路与POI权重算法拆解
2026/10/10 16:27:59
Pulse Relay Runtime 契约解析:桌面与移动端中继的端到端加密、持久化边界与移动能力治理
2026/10/10 17:13:17
一个 32B 视觉语言模型只配当编码器:H3 的“奢侈“架构
2026/10/10 17:13:17
离线环境GCC RPM安装指南:依赖解析与避坑实践
2026/10/10 17:13:17
PHP负载均衡实战:算法解析、Nginx配置与应用改造
2026/10/10 17:13:17
主动式智能体技术原理与跨端部署实践
2026/10/10 17:13:17
Spring Boot汽车维修保养系统设计:从业务流程到毕业设计落地
2026/10/10 17:08:16
MySQL索引优化实战:从B+树原理到创建删除的完整指南
2026/10/10 0:03:38
工业软件标准化路线图:国产替代的落地施工图
2026/10/10 0:03:38
VCMI安卓版实操指南:原生运行英雄无敌3的3步技术落地
2026/10/10 0:03:38
稀疏多通道盲反褶积的MATLAB算法实现与参数调优
2026/10/10 3:42:06
Jev+Agent接管浏览器:browser-use实战与jev-ultrafast性能优化
2026/10/10 3:42:01
多智能体集群实战:DeepAgents编排、MCP与A2A协议及Skills体系
2026/10/10 3:41:58
hindsight:面向LLM应用的事后可观测性工程实践
2026/10/10 3:41:56
我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频
2026/10/10 3:41:54
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证
2026/10/9 11:36:17
2026 大模型集体涨价:用 Python 做企业 Token 成本测算与选型避坑(附配置)