-
正则表达式非常消耗 CPU(如贪婪模式可能会引起回溯),慎用字符串的 split()、replaceAll() 等方法;正则表达式表达式一定预编译。
-
String.intern() 在低版本(Java 1.6 以及之前)的 JDK 上使用,可能会造成方法区(永久代)内存溢出。在高版本 JDK 中,如果 string pool 设置太小而缓存的字符串过多,也会造成较大的性能开销。
-
输出异常日志的时候,如果堆栈信息是明确的,可以取消输出详细堆栈,异常堆栈的构造是有成本的。注意:同一位置抛出大量重复的堆栈信息,JIT 会将其优化后成,直接抛出一个事先编译好的、类型匹配的异常,异常堆栈信息就看不到了。
-
避免引用类型和基础类型之间无谓的拆装箱操作,请尽量保持一致,自动装箱发生太频繁,会非常严重消耗性能。
-
根据业务场景,通过 ThreadPoolExecutor 手动创建线程池,结合任务的不同,指定线程数量和队列大小,规避资源耗尽的风险,统一命名后的线程也便于后续问题排查。
-
根据业务场景,合理选择并发容器。如选择 Map 类型的容器时,如果对数据要求有强一致性,可使用 Hashtable 或者 「Map + 锁」 ;读远大于写,使用 CopyOnWriteArrayList;存取数据量小、对数据没有强一致性的要求、变更不频繁的,使用 ConcurrentHashMap;存取数据量大、读写频繁、对数据没有强一致性的要求,使用 ConcurrentSkipListMap。
-
锁的优化思路有:减少锁的粒度、循环中使用锁粗化、减少锁的持有时间(读写锁的选择)等。同时,也考虑使用一些 JDK 优化后的并发类,如对一致性要求不高的统计场景中,使用 LongAdder 替代 AtomicLong 进行计数,使用 ThreadLocalRandom 替代 Random 类等。
- DoubleAccumulator、LongAccumulator、DoubleAdder、LongAdder是JDK1.8新增的部分,是对AtomicLong等类的改进。比如LongAccumulator与LongAdder在高并发环境下比AtomicLong更高效。








网友评论