高并发是大型架构核心,下面我详解Java并发编程@mikechen
Java并发编程
并发编程(Concurrent Programming):是指在同一段时间内处理多个任务的编程方式。

其核心目标是提升系统吞吐量、资源利用率和用户响应速度。
通过线程/进程切换实现“同时”处理多个任务(伪并行)。
多核CPU时代:真正利用多核资源,同时执行多个任务。
现代应用场景:Web服务器(同时处理成千上万请求)、大数据处理、实时系统等。
Java并发和并行
并发(Concurrency):多个任务在同一时间段内交替执行。

单核CPU(并发) 任务A ↓ 任务B ↓ 任务C ↓ 任务A
并行(Parallelism):多个任务在同一时刻真正同时执行。

多核CPU(并行) CPU1 → 任务A CPU2 → 任务B CPU3 → 任务C
Java线程周期
线程状态(6种):

start()
NEW ─────────────► RUNNABLE
│
▼
RUNNING
│
┌───────────┼──────────┐
▼ ▼ ▼
BLOCKED WAITING TIMED_WAITING
│ │ │
└───────────┴──────────┘
│
▼
TERMINATED
NEW(新建);
RUNNABLE(可运行);
BLOCKED(阻塞,等待锁);
WAITING(无限等待,wait/join/park);
TIMED_WAITING(超时等待,sleep/join(timeout));
TERMINATED(终止)。
Java线程创建

1. Thread
class MyThread extends Thread {
@Override
public void run() {
System.out.println("线程执行");
}
}
2 Runnable(推荐)
class Task implements Runnable {
@Override
public void run() {
}
}
3 Callable
Callable<String> callable = () -> {
return "success";
};
支持返回值。
4 线程池(生产环境推荐)
ExecutorService pool =
Executors.newFixedThreadPool(10);
Java线程池
线程池的核心思想是线程复用,避免频繁创建和销毁线程带来的内核态切换开销。

public ThreadPoolExecutor(
int corePoolSize, // 1. 核心线程数(常驻线程数)
int maximumPoolSize, // 2. 最大线程数(救急线程 + 核心线程)
long keepAliveTime, // 3. 空闲生存时间(非核心线程空闲多久后被销毁)
TimeUnit unit, // 4. 时间单位
BlockingQueue<Runnable> workQueue, // 5. 任务阻塞队列(存放等待执行任务的容器)
ThreadFactory threadFactory, // 6. 线程工厂(用于给线程起有业务意义的名字)
RejectedExecutionHandler handler // 7. 拒绝策略(全满时的兜底处理方案)
)
| 参数 | 作用 |
|---|---|
| corePoolSize | 核心线程数 |
| maximumPoolSize | 最大线程数 |
| keepAliveTime | 空闲存活时间 |
| workQueue | 阻塞队列 |
| handler | 拒绝策略 |
工作流程:
任务提交
│
▼
核心线程满?
│
├── 否 → 创建线程
│
└── 是
│
▼
进入队列
│
▼
队列满?
│
├── 否
│
└── 是
│
▼
创建非核心线程
Java内存模型
JMM(Java Memory Model):是Java并发的基础,定义了线程如何与内存交互。
JMM (Java Memory Model) 是一套抽象的规范,它屏蔽了各种硬件和操作系统的内存访问差异。
定义了线程和主内存之间的抽象关系,用来解决并发中的可见性、原子性、有序性问题。

① 核心概念
主内存 (Main Memory):所有线程共享的内存区域,存放所有的共享变量。
工作内存 (Work Memory):每个线程私有的本地内存,保存了该线程使用到的主内存变量的副本。
线程不能直接读写主内存,必须在工作内存中进行,然后再刷新回主内存。
② 三大特性与解决方案
可见性:一个线程修改了共享变量,其他线程要立刻看到。
解法:使用 volatile 关键字(强制失效工作内存,直连主内存)或 synchronized。
原子性:一个或多个操作在 CPU 执行过程中不可被中断。
解法:使用 synchronized 锁或 J.U.C 的 CAS 原子类(如 AtomicInteger)。
有序性:代码的执行顺序和编写顺序一致。
解法:使用 volatile 插入内存屏障,禁止指令重排序(happens-before原则)。
Java并发工具

| 工具类 | 作用 | 使用场景 |
|---|---|---|
ReentrantLock |
可重入锁 | 替代 synchronized,支持中断/超时 |
ReentrantReadWriteLock |
读写锁 | 读多写少场景 |
StampedLock |
专利锁 | 性能更高(Java 8+) |
CountDownLatch |
倒计时门闩 | 等待 N 个任务完成 |
CyclicBarrier |
循环栅栏 | N 个线程互相等待 |
Semaphore |
信号量 | 控制并发访问数 |
Exchanger |
数据交换 | 双线程交换数据 |
CompletableFuture |
异步编排 | 异步编程链式调用 |
Java并发容器
| 容器 | 线程安全实现 | 特点 | 场景 |
|---|---|---|---|
ConcurrentHashMap |
CAS + synchronized | 分段锁(JDK7)/ 桶锁(JDK8) | 高并发 Map |
CopyOnWriteArrayList |
写时复制 | 读无锁,写复制 | 读多写少 |
ConcurrentLinkedQueue |
CAS | 无界阻塞队列 | 高并发队列 |
BlockingQueue 系列 |
锁 | 阻塞队列 | 生产者 – 消费者 |
ConcurrentSkipListMap |
CAS + 锁 | 跳表,有序 Map | 有序并发 Map |