从线程基础到线程池
核心概念与基础
线程的定义与生命周期
线程定义:
线程是操作系统能够进行运算调度的最小单位,是进程中的实际运作单位。一个进 程中可以并发多个线程,每条线程并行执行不同的任务。
生命周期:
public class ThreadStateDemo {public static void main(String[] args) throws InterruptedException {Thread thread = new Thread(() -> {try {Thread.sleep(1000);synchronized (ThreadStateDemo.class) {ThreadStateDemo.class.wait(500);}} catch (InterruptedException e) {e.printStackTrace();}});// NEW状态System.out.println("创建后: " + thread.getState()); // NEWthread.start();// RUNNABLE状态System.out.println("启动后: " + thread.getState()); // RUNNABLEThread.sleep(100);// TIMED_WAITING状态(sleeping)System.out.println("sleep中: " + thread.getState()); // TIMED_WAITINGThread.sleep(1000);synchronized (ThreadStateDemo.class) {// WAITING状态(waiting)System.out.println("wait中: " + thread.getState()); // WAITINGThreadStateDemo.class.notify();}thread.join();// TERMINATED状态System.out.println("结束后: " + thread.getState()); // TERMINATED}
}多线程的优势与挑战(竞态条件、死锁等)
优势
- 提高CPU利用率
- 提升程序响应速度
- 更好的资源利用
- 简化复杂任务处理
挑战
竞态:
public class RaceConditionDemo {private int count = 0;public void increment() {count++; // 非原子操作}public static void main(String[] args) throws InterruptedException {RaceConditionDemo demo = new RaceConditionDemo();Thread t1 = new Thread(() -> {for (int i = 0; i < 1000; i++) {demo.increment();}});Thread t2 = new Thread(() -> {for (int i = 0; i < 1000; i++) {demo.increment();}});t1.start();t2.start();t1.join();t2.join();// 结果可能小于2000System.out.println("最终结果: " + demo.count);}
}死锁:
public class DeadlockDemo {private static final Object lock1 = new Object();private static final Object lock2 = new Object();public static void main(String[] args) {Thread t1 = new Thread(() -> {synchronized (lock1) {System.out.println("Thread1持有lock1");try { Thread.sleep(100); } catch (InterruptedException e) {}synchronized (lock2) {System.out.println("Thread1持有lock2");}}});Thread t2 = new Thread(() -> {synchronized (lock2) {System.out.println("Thread2持有lock2");try { Thread.sleep(100); } catch (InterruptedException e) {}synchronized (lock1) {System.out.println("Thread2持有lock1");}}});t1.start();t2.start();}
}Java 线程的实现方式:Thread 类与 Runnable 接口
JVM 内存模型与线程安全
主内存与工作内存的关系
主内存:就是我们所知的电脑内存条(RAM)。它是所有程序共享的、容量较大但速度相对较慢的存储区域。
工作内存:这里指的是CPU高速缓存。为了弥补CPU超高的运算速度与主内存相对较慢的读写速度之间的巨大差距,现代CPU都设计了多级缓存(L1, L2, L3)。每个CPU核心都有自己的缓存。
把主内存想象成公司中央文件柜(所有人共享,但距离远,速度慢)。
把工作内存(CPU缓存)想象成每个员工自己办公桌上的文件夹(私人专用,距离近,速度快)。
员工(CPU)工作时,会先把中央文件柜的文件复印一份到自己的文件夹里。修改文件也是在复印件上改。公司有一套流程(MESI协议)来确保当某个员工修改了文件后,其他员工的复印件会作废或更新,从而保证大家最终看到的都是最新版本。
同步机制:synchronized 与 Lock 的实现差异

线程池
线程池的组成部分
//把线程池看作一个公司团队
ThreadPoolExecutor executor = new ThreadPoolExecutor(corePoolSize, // 核心线程数 -> 正式员工数量maximumPoolSize, // 最大线程数 -> 最大员工数量(含正式+临时)keepAliveTime, // 临时工空闲存活时间unit, // 时间单位workQueue, // 任务队列 -> 待办任务列表threadFactory, // 线程工厂 -> HR招聘方式handler // 拒绝策略 -> 项目爆满时的应对策略
);线程池的工作流程


