Java|业务常见错误(待完善)

Java [字体···] [宽度···]


本文是我学习极客时间《Java 业务常见错误 100 例》专栏的笔记,专栏仍在学习中,在学习过程中对一些重要知识的梳理。(本文仍在完善中)

01

Tomcat 工作线程使用线程池复用线程,ThreadLocal 进行缓存数据,如果使用完毕不进行清理会造成污染。

使用了线程安全的并发工具,并不代表所有线程安全。

ConcurrentHashMap 对外提供的方法或能力限制:

1、使用了 ConcurrentHashMap 不代表它的多个操作之间的状态时一致的,确保状态一致需要手动枷锁 2、注入 size、isEmpty、containsValue 等聚合方法,在并发情况下可能反应 ConcurrentHashMap 的中间状态。这些方法的返回值,只能用作参考,不能用于控制(e.g. 先检查后执行) 3、诸如 putAll 这样的聚合方法也不能确保原子性,在 putAll 的过程中去获取数据可能获取到部分数据

没有充分了解并发工具的特性,从而无法发挥其威力。

02

不建议使用 Executors 提供的快捷方法创建线程。 线程池的核心参数:核心线程数、最大线程数、线程回收时间、工作队列类型、拒绝策略。 任何时候,都应该为自定义线程池指定有意义的名字,以方便排查问题。

线程池工作行为: 1、不会初始化 corePoolSize 个线程,有任务来了才创建工作线程; 2、当核心线程满了之后不会立即创建线程,而是把任务堆积到工作队列中; 3、当工作队列满了后扩容线程池,一致到线程个数到 maximumPoolSize 为止; 4、如果工作队列满且线程数到达最大线程还有任务过来,按照拒绝策略处理; 5、当线程数大于核心线程,线程等待 keepAliveTime 还没有任务处理就收缩到核心线程数量

声明线程池后立即调用 prestartAllCoreThreads 方法,来启动所有核心线程; 传入 true 给 allowCoreThreadTimeOut 方法,来让线程池在空闲的时候同样回收核心线程。

04

注意鉴别客户端 SDK 是否基于连接池。如果客户端没有使用连接池,而直接是 TCP 连接,那就要考虑每次建立 TCP 连接开销,并且因为 TCP 基于字节流,在多线程的情况下对统一连接进行复用,可能产生安全问题。

连接管理: XXXPool 连接池 XXXClient 内部通过连接池管理连接 XXXConnection 未使用连接池的连接

(待完善)

Top↑