
线程状态不是背的是看的NEW、RUNNABLE、BLOCKED、WAITING、TIMED_WAITING、TERMINATED这六个状态背下来不难难的是知道线程卡在哪儿。线上CPU飙高jstack打出来的线程栈里BLOCKED是在等锁WAITING是在等通知TIMED_WAITING多半在sleep或者带超时的wait。看不懂线程状态排查问题就是盲人摸象。一个线程池满了任务在队列里排着线程在等锁锁被另一个慢SQL占着环环相扣你得会顺藤摸瓜。线程池别再用Executors了Executors.newFixedThreadPool和newCachedThreadPool阿里规范明令禁止。前者队列无界任务堆积到OOM后者线程数无上限请求一多就创建大量线程直接拖垮系统。线程池必须手动new七个参数一个一个想清楚。核心线程数看业务是CPU密集还是IO密集队列用有界拒绝策略选CallerRunsPolicy让调用方跑自然形成背压。别嫌麻烦线上事故都是从图省事开始的。锁从synchronized到ReentrantLocksynchronized是JVM内置锁自动释放但不可中断、不超时、不公平。ReentrantLock手动释放可中断、可超时、可公平还能多个条件变量。选哪个不看性能看场景。简单同步用synchronized复杂协调用ReentrantLock。但记住锁的粒度越小越好锁的时间越短越好。把耗时的IO操作放在锁外面别让一个慢请求拖死所有线程。JMM与volatile看不见的坑最深Java内存模型规定每个线程有自己的工作内存共享变量从主内存拷贝。一个线程改了另一个线程可能看不见。volatile保证可见性和禁止指令重排但不保证原子性。i用volatile修饰照样丢数据因为读-改-写不是原子操作。要原子性用AtomicInteger或者加锁。双重检查锁单例里instance必须加volatile否则可能拿到半初始化对象。这个坑面试必问线上必踩。CAS无锁编程的基石compareAndSwap比较并交换CPU原语原子操作。AtomicInteger、AtomicReference底层都是CAS。CAS避免了锁的开销但带来了ABA问题和自旋消耗。ABA问题用版本号解决AtomicStampedReference就是干这个的。自旋消耗在竞争激烈时反而比锁慢所以LongAdder出现了分段累加最后汇总高并发下比AtomicLong快得多。没有银弹只有权衡。高并发设计分流、限流、异步高并发的核心不是让一个接口扛住一万并发是把一万并发分散到十个接口、十台机器、十个线程上。分流靠负载均衡限流靠令牌桶和漏桶异步靠消息队列和CompletableFuture。能异步的别同步能并行的别串行能缓存的别查库。一个请求进来先看缓存缓存没有再查库查库用连接池连接池大小要跟数据库承受能力匹配。每一步都算清楚并发才上得去。多线程与高并发说到底是对资源的精细调度。线程是资源锁是资源数据库连接是资源CPU时间片也是资源。把合适的任务放到合适的线程上用合适的锁保护合适的临界区在合适的时机释放资源。这三点做到了高并发就不是玄学。别指望一篇文章解决所有问题但这一篇够你搭起一个不塌的架子。