线程基础
线程的创建
1. 继承Thread类
java
public class MyThread extends Thread {
@Override
public void run() {
System.out.println("线程执行");
}
}
// 使用
MyThread thread = new MyThread();
thread.start();2. 实现Runnable接口
java
public class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println("线程执行");
}
}
// 使用
Thread thread = new Thread(new MyRunnable());
thread.start();3. 实现Callable接口
java
public class MyCallable implements Callable<String> {
@Override
public String call() throws Exception {
return "执行结果";
}
}
// 使用
FutureTask<String> task = new FutureTask<>(new MyCallable());
Thread thread = new Thread(task);
thread.start();
String result = task.get(); // 获取返回值4. 线程池
java
ExecutorService executor = Executors.newFixedThreadPool(5);
executor.submit(() -> {
System.out.println("线程池执行任务");
});线程的生命周期
New
↓
Runnable ←→ Running
↓ ↓
Terminated Blocked/Waiting/Timed Waiting状态说明
- NEW:新建状态,线程被创建但还未调用start()
- RUNNABLE:就绪状态,等待CPU调度
- RUNNING:运行状态,正在执行
- BLOCKED:阻塞状态,等待获取锁
- WAITING:等待状态,等待其他线程通知
- TIMED_WAITING:超时等待状态
- TERMINATED:终止状态,线程执行完毕
线程的方法
常用方法
java
Thread thread = new Thread(() -> {
System.out.println("执行");
});
thread.start(); // 启动线程
thread.join(); // 等待线程结束
thread.interrupt(); // 中断线程
thread.isAlive(); // 判断线程是否存活
Thread.sleep(1000); // 休眠1秒
Thread.yield(); // 让出CPU
Thread.currentThread(); // 获取当前线程sleep vs wait
java
// sleep:不释放锁,到时间自动醒来
Thread.sleep(1000);
// wait:释放锁,需要notify/notifyAll唤醒
synchronized(obj) {
obj.wait();
}线程同步
synchronized关键字
java
// 同步方法
public synchronized void method() {
// 同步代码
}
// 同步代码块
public void method() {
synchronized(this) {
// 同步代码
}
}
// 静态同步方法
public static synchronized void method() {
// 同步代码
}volatile关键字
java
// 保证可见性和有序性,但不保证原子性
private volatile boolean flag = false;
public void setFlag() {
flag = true;
}
public void checkFlag() {
while (!flag) {
// 等待
}
}线程间通信
wait/notify机制
java
public class ProducerConsumer {
private Queue<Integer> queue = new LinkedList<>();
private int maxSize = 10;
public synchronized void produce() throws InterruptedException {
while (queue.size() == maxSize) {
wait(); // 队列满,生产者等待
}
queue.add(1);
notify(); // 通知消费者
}
public synchronized void consume() throws InterruptedException {
while (queue.isEmpty()) {
wait(); // 队列空,消费者等待
}
queue.poll();
notify(); // 通知生产者
}
}Lock + Condition
java
public class ProducerConsumer {
private Queue<Integer> queue = new LinkedList<>();
private int maxSize = 10;
private Lock lock = new ReentrantLock();
private Condition notFull = lock.newCondition();
private Condition notEmpty = lock.newCondition();
public void produce() throws InterruptedException {
lock.lock();
try {
while (queue.size() == maxSize) {
notFull.await();
}
queue.add(1);
notEmpty.signal();
} finally {
lock.unlock();
}
}
public void consume() throws InterruptedException {
lock.lock();
try {
while (queue.isEmpty()) {
notEmpty.await();
}
queue.poll();
notFull.signal();
} finally {
lock.unlock();
}
}
}线程池详解
线程池的优势
- 降低资源消耗
- 提高响应速度
- 提高线程的可管理性
创建线程池
java
// 固定大小线程池
ExecutorService executor = Executors.newFixedThreadPool(5);
// 单线程线程池
ExecutorService executor = Executors.newSingleThreadExecutor();
// 可缓存线程池
ExecutorService executor = Executors.newCachedThreadPool();
// 定时任务线程池
ScheduledExecutorService executor = Executors.newScheduledThreadPool(5);
// 自定义线程池(推荐)
ThreadPoolExecutor executor = new ThreadPoolExecutor(
5, // 核心线程数
10, // 最大线程数
60L, // 空闲线程存活时间
TimeUnit.SECONDS, // 时间单位
new LinkedBlockingQueue<>(100), // 任务队列
Executors.defaultThreadFactory(), // 线程工厂
new ThreadPoolExecutor.AbortPolicy() // 拒绝策略
);线程池执行流程
提交任务
↓
核心线程数未满?
是 → 创建核心线程执行
否 ↓
任务队列未满?
是 → 加入队列等待
否 ↓
最大线程数未满?
是 → 创建非核心线程执行
否 → 执行拒绝策略💡 提示
这是一个demo文档,欢迎补充更多线程相关内容。