多线程相关知识点系统整理
一、基本概念
1. 程序、进程、线程
- 程序:静态的代码集合,是指令和数据的有序集合,不具备运行意义
- 进程:程序的一次执行过程,系统进行资源分配和调度的独立单位,有自己的内存空间
- 线程:进程内的一个执行单元,是CPU调度和执行的基本单位,共享进程的内存空间
- 管程:一种同步机制,是一个特殊的模块,用来管理共享资源的访问,确保同一时间只有一个线程访问共享资源
2. CPU与多线程执行
- 单核CPU:同一时间只能执行一个线程,通过快速切换线程实现并发执行
- 多核CPU:可以真正实现并行执行多个线程,每个核心同时处理一个线程
二、线程基础
1. 线程的特性
- 多个执行路径,共享进程资源
- 线程状态包括:新建、就绪、运行、阻塞、终止
- 线程执行顺序是随机的,由CPU调度决定
- 多线程交替执行,通过CPU时间片轮转实现
2. 线程的创建方式
方式一:继承Thread类
- 自定义类继承
Thread
类 - 覆写
run()
方法,编写线程执行逻辑 - 创建线程对象,调用
start()
方法启动线程
class MyThread extends Thread {
@Override
public void run() {
// 线程执行逻辑
}
}
// 使用
MyThread thread = new MyThread();
thread.start(); // 启动线程
关键说明:
run()
方法:线程执行体,包含线程要执行的逻辑start()
方法:启动线程,使线程进入就绪状态,由JVM调用run()
方法run()
不可以显式调用(直接调用只是普通方法调用)start()
只能调用一次,多次调用会抛出IllegalThreadStateException
方式二:实现Runnable接口
- 自定义类实现
Runnable
接口 - 实现
run()
方法 - 创建
Thread
对象,将Runnable
实例作为参数传入 - 调用
start()
方法启动线程
class MyRunnable implements Runnable {
@Override
public void run() {
// 线程执行逻辑
}
}
// 使用
Thread thread = new Thread(new MyRunnable());
thread.start();
方式三:实现Callable接口(功能更强大)
- 自定义类实现
Callable<T>
接口(T为返回值类型) - 覆写
call()
方法,包含线程执行逻辑 - 创建
FutureTask
对象,将Callable
实例作为参数传入 - 创建
Thread
对象,将FutureTask
实例作为参数传入 - 调用
start()
方法启动线程
class MyCallable implements Callable<Integer> {
@Override
public Integer call() throws Exception {
// 线程执行逻辑,有返回值
return 0;
}
}
// 使用
FutureTask<Integer> futureTask = new FutureTask<>(new MyCallable());
Thread thread = new Thread(futureTask);
thread.start();
Callable的优势:
- 可以返回结果(通过
FutureTask.get()
获取) - 可以抛出异常,便于错误处理
- 更适合需要返回结果的多线程任务
FutureTask说明:
FutureTask
实现RunnableFuture
接口RunnableFuture
继承Runnable
和Future
接口- 每个线程需要独立的
FutureTask
对象,才能实现多线程并发 - 调用
get()
方法会阻塞当前线程,直到获取到返回结果
3. 线程相关重要方法
Thread.currentThread()
:静态方法,返回当前正在执行的线程对象Thread.sleep(long millis)
:让当前线程休眠指定毫秒数,进入阻塞状态synchronized
:同步关键字,用于实现线程同步,确保共享资源安全
4. 共享资源处理
- 多线程操作的公共资源必须设计为共享的,通常使用
static
修饰 - 若不使用
static
,每个线程会持有独立的资源副本,无法实现资源共享 - 共享资源访问需要同步机制(如
synchronized
),避免数据不一致
三、高级特性与工具
1. 匿名内部类创建线程
// 匿名内部类方式创建Thread子类
new Thread() {
@Override
public void run() {
// 线程逻辑
}
}.start();
// 匿名内部类方式创建Runnable实现
new Thread(new Runnable() {
@Override
public void run() {
// 线程逻辑
}
}).start();
2. Lambda表达式与线程
利用Lambda表达式简化线程创建(适用于函数式接口):
// Runnable接口的Lambda表达式实现
new Thread(() -> {
// 线程执行逻辑
}).start();
// Callable接口的Lambda表达式实现
FutureTask<Integer> futureTask = new FutureTask<>(() -> {
// 线程执行逻辑
return 100;
});
new Thread(futureTask).start();
3. CountDownLatch
线程同步工具类,用于等待其他线程完成后再执行:
CountDownLatch latch = new CountDownLatch(3); // 计数器为3
// 其他线程执行完成后调用
latch.countDown(); // 计数器减1
// 主线程等待
latch.await(); // 等待计数器变为0
4. 常用工具方法
FileUtils.copyURLToFile(URL source, File destination)
:Apache Commons IO工具类中的方法,用于将URL资源复制到文件
四、Lombok注解相关
@Data
:生成getter、setter、toString、equals、hashCode等方法@AllArgsConstructor
:生成全参数构造方法@ToString
:生成toString方法@Accessors(chain = true)
:支持链式编程,使setter方法返回当前对象
示例:
@Data
@AllArgsConstructor
@Accessors(chain = true)
public class User {
private String name;
private int age;
}
// 链式调用
User user = new User();
user.setName("张三").setAge(20);