文章介绍了 JDK 动态代理和 CGLIB 的原理、区别及使用场景。JDK 代理基于接口,需要实现 InvocationHandler,适用于实现了接口的类;CGLIB 通过 ASM 生成目标类的子类,可对未实现接口的类进行代理,但不能代理 final 方法。Spring 默认在有接口时使用 JDK 代理,无接口时使用 CGLIB,也可强制指定。性能上 JDK 在 JDK6 以后得到优化,调用次数少时更快,大量调用时 CGLIB 可能占优。文末提供了两者的创建代码示例。

在 Java 开发中应尽量复用对象,避免重复创建。使用字符串字面量而非 new String 可共享常量池;不可变的 String 用于固定文本,拼接时选用 StringBuilder (单线程)或 StringBuffer (线程安全)。Boolean 取值应使用 Boolean.valueOf,避免 new Boolean 产生新实例。尽量使用基本类型,避免自动装箱/拆箱带来的额外对象。正则匹配时应提前编译 Pattern,别在循环中调用 String.matches(),可显著提升性能。通过这些细节可降低内存占用并提升运行速度。

Java开发中资源释放是常见问题,传统方式如`try...finally`块易导致代码冗余、可读性差且易出错。文章探讨了如何更优雅地释放资源,重点推荐使用Java 7引入的`try-with-resources`语句,它能自动关闭实现了`AutoCloseable`接口的资源,简化代码并避免资源泄露。 此外,文章也提供了一种手动释放资源的方案,即抽取公共的`close`方法,但强调了资源释放顺序的重要性。最终,文章认为`try-with-resources`是更简洁、更可靠的资源释放方式,推荐开发者优先采用。

线程池通过复用有限数量的线程来避免频繁创建和销毁线程的开销。`execute()`先尝试在核心线程数范围内新增 `Worker`,否则把任务放入工作队列;当队列已满或线程数已达上限时,再尝试创建最大线程数的 `Worker`。`Worker` 实现 `Runnable`,其 `run()` 调用 `runWorker()`,在一个 `while` 循环中不断从 `firstTask` 或工作队列 `getTask()` 取出任务并直接执行 `task.run()`,而不再创建新线程。线程结束后仍保持在循环中等待下一个任务,从而实现线程的重复利用。整个过程依赖原子计数、CAS 增减线程数以及锁保护的 `workers` 集合,确保线程安全和正确的拒绝策略。

文章说明了并发事务导致的四类异常:脏写(未提交事务被后写覆盖后回滚导致数据丢失),脏读(读取了未提交的数据而后被回滚),不可重复读(同事务期间多次读取已提交的其他事务修改导致结果不一致),幻读(同一查询条件多次执行因其他事务插入导致结果集增多)。随后列出四种事务隔离级别及其防护能力:READ‑UNCOMMITTED 允许脏读;READ‑COMMITTED 防脏读;REPEATABLE‑READ 防脏读和不可重复读但仍可能幻读;SERIALIZABLE 防全部异常。MySQL 默认使用 REPEATABLE‑READ 隔离级别。

本文分析了Java并发包中核心类AQS(AbstractQueuedSynchronizer)的源码实现。AQS通过volatile修饰的state状态和基于双向链表的CLH等待队列来管理同步资源,支持独占和共享两种模式。它采用模板方法设计模式,子类通过重写tryAcquire等方法来实现具体的同步逻辑。文章详细剖析了Node类及其状态,并结合自定义独占锁Mutex示例,阐述了acquire、addWaiter等方法在线程排队与自旋获取资源中的具体执行流程。