第五周总结
Java 学习第五周总结
一、学习概述
本周学习内容涵盖 Java 并发编程进阶、NIO 编程以及软件工程实践。在并发编程方面,深入学习了 CopyOnWriteArrayList、BlockingQueue 等并发集合的应用,掌握了 StampedLock 的锁优化技术及线程池调优策略。NIO 部分重点学习了 Buffer 与 Channel 的操作及文件复制技术。此外,通过阅读《构建之法》,对软件构建的生命周期、挑战及实践方法有了系统认知。
二、并发集合与高级锁机制
(一)并发集合进阶
- CopyOnWriteArrayList
- 核心特性:适用于读多写少场景,通过复制数组实现线程安全,遍历时获取数据快照,避免 ConcurrentModificationException。
- 使用场景:日志记录、配置信息读取等读操作频繁的场景。
- 代码示例:
CopyOnWriteArrayList
list.add("Java");
list.add("并发编程");
list.forEach(System.out::println); // 安全遍历
2. BlockingQueue
4. 接口实现:常用实现类有 LinkedBlockingQueue、ArrayBlockingQueue,支持阻塞式 put/take 操作。
5. 生产者 - 消费者模型:
BlockingQueue
// 生产者线程
new Thread(() -> {
try {
queue.put(100); // 队列满时阻塞
} catch (InterruptedException e) {}
}).start();
// 消费者线程
new Thread(() -> {
try {
int num = queue.take(); // 队列空时阻塞
} catch (InterruptedException e) {}
}).start();
3. ConcurrentLinkedQueue
6. 无锁实现:基于 CAS 操作实现非阻塞线程安全,适合高并发场景。
7. 性能优势:无锁机制避免锁竞争,适用于任务队列等高频操作场景。
8. 代码示例:
ConcurrentLinkedQueue
queue.offer("Task1");
queue.offer("Task2");
String task = queue.poll(); // 非阻塞获取任务
(二)锁优化与 StampedLock
- StampedLock 特性
- 三种锁模式:
- 写锁(独占):writeLock() - 排他性锁,获取时阻塞其他线程。
- 悲观读锁(共享):readLock() - 允许多线程同时读,写操作阻塞。
- 乐观读(无锁):tryOptimisticRead() - 不获取锁,通过validate(stamp)验证数据一致性。
- 锁转换风险:读锁升级为写锁可能导致死锁,需谨慎使用。
- 代码示例
class Point {
private double x, y;
private final StampedLock lock = new StampedLock();
// 写操作(独占锁)
void move(double deltaX, double deltaY) {
long stamp = lock.writeLock();
try {
x += deltaX;
y += deltaY;
} finally {
lock.unlockWrite(stamp);
}
}
// 乐观读(无锁模式)
double distanceFromOrigin() {
long stamp = lock.tryOptimisticRead();
double currentX = x, currentY = y;
if (!lock.validate(stamp)) { // 验证期间是否被修改
stamp = lock.readLock(); // 退化为悲观读锁
try {
currentX = x;
currentY = y;
} finally {
lock.unlockRead(stamp);
}
}
return Math.sqrt(currentX * currentX + currentY * currentY);
}
}
三、线程池调优与 NIO 编程
(一)线程池调优策略
- 核心参数配置
ThreadPoolExecutor executor = new ThreadPoolExecutor(
5, // corePoolSize:核心线程数(常驻)
10, // maximumPoolSize:最大线程数
60, // keepAliveTime:空闲线程存活时间
TimeUnit.SECONDS,
new LinkedBlockingQueue<>(100), // 任务队列
new ThreadPoolExecutor.AbortPolicy() // 拒绝策略
);
2. 拒绝策略对比
策略 行为
AbortPolicy 直接抛出 RejectedExecutionException
CallerRunsPolicy 由提交任务的线程直接执行任务
DiscardPolicy 静默丢弃新任务
DiscardOldestPolicy 丢弃队列最旧任务并重试提交
3. 监控与调优工具
11. 关键指标:活跃线程数、队列堆积量、任务完成时间、拒绝任务数。
12. 工具推荐:Spring Boot Actuator(监控端点)、JMX(Java Management Extensions)、Arthas(线上诊断工具)。
(二)NIO 之 Buffer 与 Channel 操作
- Buffer 读写流程
// 1. 分配Buffer(容量10)
ByteBuffer buffer = ByteBuffer.allocate(10);
// 2. 写入数据
buffer.put((byte)'J');
buffer.put((byte)'A');
buffer.flip(); // 切换为读模式(position=0, limit=2)
// 3. 读取数据
while (buffer.hasRemaining()) {
System.out.print((char)buffer.get()); // 输出 "JA"
}
// 4. 清空Buffer(切换为写模式)
buffer.clear();
2. 文件 Channel 复制示例
try (FileChannel src = FileChannel.open(Paths.get("source.txt"));
FileChannel dest = FileChannel.open(
Paths.get("dest.txt"),
StandardOpenOption.WRITE,
StandardOpenOption.CREATE)) {
src.transferTo(0, src.size(), dest); // 零拷贝高效传输
} catch (IOException e) {
e.printStackTrace();
}
四、《构建之法》实践思考
(一)软件构建生命周期
- 需求分析与规格说明
- 核心要点:建立灵活的需求管理机制,应对需求变更;将用户需求转化为明确的规格说明,确保开发方向一致。
- 实践建议:采用用户故事(User Story)梳理需求,使用需求跟踪矩阵管理变更。
- 设计与实现阶段
- 架构设计:关注系统可维护性、可扩展性,选择合适的设计模式(如 MVC、微服务架构)。
- 编码规范:遵循阿里巴巴 Java 开发手册,使用版本控制工具(Git)管理代码。
- 测试与交付
- 测试策略:结合单元测试(JUnit)、集成测试(Spring Test)、自动化测试(Selenium)。
- 部署优化:采用 CI/CD 流水线(Jenkins/GitLab CI)实现自动化部署。
(二)软件构建挑战与应对 - 需求变更管理
- 影响分析:评估变更对进度、成本、质量的影响,确定变更优先级。
- 工具支持:使用 Jira/Trello 管理需求变更,保持需求文档与代码的一致性。
- 团队协作优化
- 沟通机制:每日站会(Scrum)、定期技术评审,使用 Confluence 记录知识。
- 角色分工:明确产品经理、架构师、开发人员的职责,减少沟通损耗。
(三)敏捷开发与质量保证 - 敏捷实践应用
- Scrum 框架:通过迭代(Sprint)交付可工作软件,定期进行回顾(Retrospective)。
- Kanban 看板:可视化任务流程,优化工作项流动效率。
- 持续集成(CI)
- 流水线配置:代码提交触发构建 - 测试 - 静态分析流程,使用 SonarQube 进行代码质量检测。
- 自动化测试:单元测试覆盖率不低于 80%,集成测试覆盖核心业务流程。
五、本周学习总结与反思
(一)学习成果 - 掌握 CopyOnWriteArrayList、BlockingQueue 等并发集合的适用场景与实现原理。
- 理解 StampedLock 的三种锁模式,能在读写频繁场景中优化锁性能。
- 掌握线程池核心参数调优方法,能根据业务场景配置合理的线程池策略。
- 熟练使用 NIO 的 Buffer 与 Channel 进行高效 IO 操作,实现文件零拷贝。
- 系统理解软件构建的生命周期,掌握敏捷开发、持续集成等工程实践方法。
(二)存在问题 - 对 StampedLock 的锁转换死锁风险理解不够深入,需通过源码分析加深认知。
- 线程池调优缺乏实际业务场景经验,参数配置仍依赖理论推导。
- NIO 编程中对 Selector 多路复用器的应用不够熟练,未掌握高性能网络编程。
- 软件构建流程中的需求跟踪与质量度量方法实践不足,需结合项目实战强化。
(三)改进方向 - 研读 JUC 包源码,理解 ConcurrentLinkedQueue 的 CAS 实现细节。
- 通过压测工具(JMeter)模拟高并发场景,优化线程池配置。
- 学习 Netty 框架,掌握 NIO 在高性能网络服务中的应用。
- 参与开源项目或模拟项目,实践需求管理与敏捷开发流程。
(四)下周计划 - 学习 Java 网络编程,实现 Socket 通信与 HTTP 服务器。
- 深入研究数据库连接池(HikariCP)与 JDBC 编程。
- 学习分布式事务解决方案(Seata),理解 CAP 定理与 BASE 原则。
- 阅读《领域驱动设计》,探索复杂业务场景的建模方法。
浙公网安备 33010602011771号