java.util.concurrent包的核心定位是提供可组合、线程安全、有明确语义的并发构建块,而非synchronized或wait/notify的语法糖;典型工具如ArrayBlockingQueue、ForkJoinPool等直接解决生产者-消费者、任务分治等场景。

java.util.concurrent 包的核心定位是什么
它不是用来替代 synchronized 或 wait/notify 的“高级语法糖”,而是为解决典型并发场景提供**可组合、线程安全、有明确语义**的构建块。比如你不需要手写一个线程安全的生产者-消费者队列,直接用 ArrayBlockingQueue 就行;也不必自己实现任务拆分合并逻辑,ForkJoinPool 已经封装好。
哪些工具类最容易误用
常见错误不是不会用,而是没看清行为边界:
-
ConcurrentHashMap的size()返回的是近似值,高并发下可能滞后 —— 需要精确计数请改用LongAdder -
CopyOnWriteArrayList适合读多写极少的场景(如监听器列表),但每次写操作都复制整个数组,写频繁时 GC 压力大、内存占用高 -
CountDownLatch只能触发一次,想重复使用得换CyclicBarrier或重置逻辑 -
ExecutorService.submit(Runnable)返回的Future若不调用get()或isDone(),异常会静默丢失
ThreadPoolExecutor 的关键参数怎么配
不是所有线程池都该设成 newFixedThreadPool(10)。真实系统中需权衡阻塞比例、响应延迟与资源消耗:
-
corePoolSize:常驻线程数,建议设为 CPU 核心数 × (1 + 平均阻塞系数),比如 DB 调用多就往高调 -
maximumPoolSize:仅当workQueue满且仍有新任务时才创建额外线程,设太大易引发上下文切换风暴 -
keepAliveTime:对非核心线程有效,IO 密集型服务可设长些(如 60s),避免频繁启停 -
workQueue别无脑选LinkedBlockingQueue—— 它默认无界,OOM 风险高;优先考虑ArrayBlockingQueue或带拒绝策略的SynchronousQueue
CompletableFuture 和传统 Future 本质区别在哪
根本不在“异步”,而在**可编排性**:Future 是被动等待,CompletableFuture 支持链式回调、组合依赖、异常处理分流:
系统功能介绍 1 包含企业网站所必备的功能:企业信息、产品管理、人才招聘、新闻资讯、企业图片、以及视频下载等模块2 由于是从CMS系统的基础上开发而成,因此相对于一些其他的企业网站管理系统,本系统具备更强的可扩展能力,可以胜任从小型工作室到大中型企业网上门户等各种不同规模网站的需求。3 后台管理与模板完全分离,并具备非常灵活的标签技术,可以实现无限制个性化的界面定制4 操作简单,利用已经制作好的模
立即学习“Java免费学习笔记(深入)”;
CompletableFuture.supplyAsync(() -> fetchFromDB())
.thenCompose(data -> CompletableFuture.supplyAsync(() -> callRemoteAPI(data)))
.exceptionally(ex -> fallbackValue())
.thenAccept(result -> log.info("done: {}", result));
注意点:
- 默认使用
ForkJoinPool.commonPool(),CPU 密集型任务建议显式传入专用线程池,避免拖慢其他模块 -
thenApply/thenAccept等方法在前序阶段完成时同步执行,若耗时长会阻塞线程池 —— 此时应改用thenApplyAsync -
join()不抛检查异常,但若上游异常未处理,调用join()会直接抛CompletionException,包装了原始异常
并发库的复杂度不在 API 数量,而在每个类背后隐含的线程模型假设和状态流转规则。用错一个队列或一个拒绝策略,可能让系统在压测时突然卡死,而不是报错——这种问题往往要靠日志和线程 dump 才能定位。










